我只想要一个这样的类型:
type ObjectWithAnyKey = { [key: string]: string };
Run Code Online (Sandbox Code Playgroud)
允许除钥匙外的所有钥匙foo
。
怎么做?
jca*_*alz 21
我认为在这种情况下,您可以使用以下定义:
type ObjectWithAnyKeyExceptFoo = {
[key: string]: string
} & { foo?: never };
Run Code Online (Sandbox Code Playgroud)
该类型{foo?: never}
有一个名为 的可选属性foo
,其类型为never
(实际上与undefined
可选属性相同)。因此,如果您有一个名为 的属性foo
,则它不能具有定义的值。实际上,因为undefined & string
is never
,您根本不能拥有foo
财产。让我们确保它有效:
function acceptAnyKeyAcceptFoo(obj: ObjectWithAnyKeyExceptFoo) { }
acceptAnyKeyAcceptFoo({}); // okay
acceptAnyKeyAcceptFoo({ a: "123" }); // okay
acceptAnyKeyAcceptFoo({ a: "123", foo: "oops" }); // error!
// ----------------------------> ~~~
// Type 'string' is not assignable to type 'undefined'.
acceptAnyKeyAcceptFoo({ a: "123", foo: undefined }); // error!
// ----------------> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Type 'undefined' is not assignable to type 'string'.
Run Code Online (Sandbox Code Playgroud)
看起来挺好的。
更多技术内容如下:
请注意,这里使用交集( &
) 有点奇怪,甚至可能有点作弊。使用索引签名,手动指定的属性foo
也需要具有可分配给其索引签名属性类型的值。以下不起作用,因为它违反了:
type BadDefn = {
[key: string]: string;
foo?: never; // error!
//~~~ <-- undefined is not assignable to string
}
Run Code Online (Sandbox Code Playgroud)
由于foo
可能是undefined
,但string
不是,编译器不高兴。不要介意来自索引签名的大多数值实际上是undefined
和不是string
(例如,const obj: ObjectWithAnyKeyExceptFoo = {a: "123"}
有一个a
type的属性string
,但是如果你访问它的b
属性呢?你会undefined
在运行时得到,但编译器说string
)。 但我猜这就是索引签名的方式。
交集定义与上面不允许的类型本质上是一样的,只是它避开了编译器错误。故意这样做会违反索引签名(请参阅此问题)通常会出现问题,但我们实际上并不想使用该违反属性。我们根本不需要foo
属性,而且由于编译器将foo
属性视为string & undefined
,即never
,实际上更适合此用例。
可以制作像这样的非违规单一类型:
type OkayDefnButPossiblyUndefined = {
[key: string]: string | undefined;
foo?: never;
}
Run Code Online (Sandbox Code Playgroud)
如果您想表示obj.b
isundefined
和 not string
,这实际上是合理的,但如果您喜欢当前的索引签名行为,则可能不是最合适的。还有这个:
type AlsoOkayButRequiresFoo = {
[key: string]: string;
foo: never;
}
Run Code Online (Sandbox Code Playgroud)
更糟糕的是,因为foo
成为必需的属性并且很难实际初始化这种类型的东西。
结束技术性的东西
好的,希望有帮助。祝你好运!
Gib*_*olt 11
Omit
在 TypeScript (3.5+) 中使用关键字type ObjectWithAnyKey = {
[key: string]: string
}
type ObjectWithAnyKeyButFoo = Omit<ObjectWithAnyKey, 'foo'>
Run Code Online (Sandbox Code Playgroud)
对于排除多个属性:
type ObjectWithAnyKeyButFooOrBar = Omit<ObjectWithAnyKey, 'foo' | 'bar'>
Run Code Online (Sandbox Code Playgroud)
重新定义特定属性:
type ObjectWithAnyKeyAndUniqueFooBar = Omit<ObjectWithAnyKey, 'foo' | 'bar'> & {
bar: number
foo: Record<string, number>
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4388 次 |
最近记录: |