相关疑难解决方法(0)

打字稿:防止分配具有比目标接口中指定的更多属性的对象

假设我有一个典型的“用户”对象,它具有通常的用户名、电子邮件、密码等属性。我想创建和管理一个对象,该对象是此类用户的真正“子集”,并保证不包含密码。这是一个粗略的方法:

interface IUserSansPassword {
    username: string;
    email: string;
}

class UserSansPassword implements IUserSansPassword { ... }

interface IUser extends IUserSansPassword {
    password: string;
}

class User implements IUser { ... }
Run Code Online (Sandbox Code Playgroud)

在尝试创建 type 的对象时IUserSansPassword,我预计会出现以下错误:

const userSansPassword: UserSansPassword = new User(); // No TS Error †††
Run Code Online (Sandbox Code Playgroud)

但是,我没有收到 TS 错误,因为令我惊讶的是,TS 不禁止分配具有已建立的“额外”属性的对象。这是令人惊讶的,因为如果我尝试直接使用额外的属性进行定义,我会得到一个错误,如下所示:

const userSansPassword: IUserSansPassword = {
    username: 'jake',
    email: 'jake@snake.com',
    password: '' // TS Error ***
}
Run Code Online (Sandbox Code Playgroud)

我的问题总结:

  1. 为什么 TS 会这样?允许分配给具有过多属性的类型是不是很糟糕(因此为什么在上面的 *** 中出现错误)?

  2. 是否有我可以采用的 TS 设置或技术使 TS 在上面的 ††† 中出错?

typescript

14
推荐指数
1
解决办法
3091
查看次数

如何以适当的类型安全方式迭代 Record 键?

让我们在一些属性上构建一个示例记录。

type HumanProp = 
    | "weight"
    | "height"
    | "age"

type Human = Record<HumanProp, number>;

const alice: Human = {
    age: 31,
    height: 176,
    weight: 47
};
Run Code Online (Sandbox Code Playgroud)

对于每个属性,我还想添加一个人类可读的标签:

const humanPropLabels: Readonly<Record<HumanProp, string>> = {
    weight: "Weight (kg)",
    height: "Height (cm)",
    age: "Age (full years)"
};
Run Code Online (Sandbox Code Playgroud)

现在,使用这个 Record 类型和定义的标签,我想迭代两个具有相同键类型的记录。

function describe(human: Human): string {
    let lines: string[] = [];
    for (const key in human) {
        lines.push(`${humanPropLabels[key]}: ${human[key]}`);
    }
    return lines.join("\n");
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到一个错误:

Element implicitly has an 'any' type because expression of …
Run Code Online (Sandbox Code Playgroud)

typescript

13
推荐指数
2
解决办法
5440
查看次数

当 K 是两者的共享属性时,类型“fooType[K]”不可分配给类型“barType[K]”

在下面的代码中,我尝试对于 的每个属性foo,检查 中的属性是否barnullish,如果是,则bar使用 中的属性覆盖 的该属性foo

type fooType = {
  a?: string
  b?: number
}

type barType = fooType & {
  c: string
}

const foo: fooType = {
  a: 'hello',
  b: 5,
}

const bar: barType = {
  a: 'greetings',
  b: undefined,
  c: 'not in foo',
}

const fooKeys = Object.keys(foo) as Array<keyof typeof foo>
fooKeys.forEach((k) => {
  bar[k] ??= foo[k]
})
Run Code Online (Sandbox Code Playgroud)

我收到错误:Type 'string' is not assignable to type …

typescript typescript-generics

7
推荐指数
1
解决办法
111
查看次数

标签 统计

typescript ×3

typescript-generics ×1