在Typescript联合中键入属性的getter
我有这些类型的脚本类型:在Typescript联合中键入属性的getter,typescript,types,Typescript,Types,我有这些类型的脚本类型: type A = { a: string } type B = { b: number, } type C = number; type U = A | B | C; 我试图编写一个函数,给定U类型之一的属性,返回属性值或未定义的 在Javascript中,应该是这样的: function getProp(prop: P) { return (thing) => { if (typeof thing === 'object' &
type A = {
a: string
}
type B = {
b: number,
}
type C = number;
type U = A | B | C;
我试图编写一个函数,给定U
类型之一的属性,返回属性值或未定义的
在Javascript中,应该是这样的:
function getProp(prop: P) {
return (thing) => {
if (typeof thing === 'object' && prop in thing) {
return thing[prop]
}
return undefined;
}
}
例如:
const u: U = ...;
const a: string | undefined = getProp('a')(u);
我试过这个:
type KeysOfUnion<T> = T extends any ? keyof T : never; // because `keyof U` return `never`
function getProp<P extends KeysOfUnion<U>>(prop: P) {
return (thing: U): U[P] => { // error: `Type 'P' cannot be used to index type 'U'.`
if (typeof thing === 'object' && prop in thing) {
return thing[prop]; // error: Type 'P' cannot be used to index type 'A | B'
}
return undefined; // error: Type 'undefined' is not assignable to type 'U[P]'.
}
}
const a: string | undefined = getProp('a')(u);
typekeysofunion=T扩展了什么?T的键:从不;//因为'keyof'return'永远不会`
函数getProp(prop:P){
return(thing:U):U[P]=>{//error:'Type'P'不能用于索引类型'U'`
if(typeof thing==='object'&&prop in thing){
return thing[prop];//错误:类型“P”不能用于索引类型“A | B”
}
return undefined;//错误:类型“undefined”不能分配给类型“U[P]”。
}
}
常数a:string | undefined=getProp('a')(u);
但这是无效的。如果我想正确地键入这个奇怪的函数,我想我必须为
U[P]
找到一个替代方法,但我不知道是什么。有什么想法吗?从调用方的角度来看,您可能希望getProp()
返回一个返回IdxUnion
的函数,其中IdxUnion
的定义如下:
type IdxUnion<T, K extends PropertyKey> =
T extends any ? K extends keyof T ? T[K] : undefined : never;
我之所以说“大部分”,是因为函数实现并不像您所说的那样,在给定签名的情况下它会做:如果u
是一个number
而不是一个对象,您总是在运行时返回未定义的,但是number
有toFixed
等键,所以您希望getProp('toFixed'))(123)
作为一个函数。这对于您的特定U
来说基本上不是问题,因为a
和B
会给您实际出现的未定义的,但这很奇怪。因此请小心:
const hmm = getProp('toFixed')(123);
// ((fractionDigits?: number | undefined) => string) | undefined
在getProp()
的实现中,事情更为棘手。编译器通常很难评估在未指定泛型类型(尤其是条件类型)上发生的操作的类型安全性。您在这里的最佳选择可能是告诉编译器您知道自己在做什么:
if (typeof thing === "object" && prop in thing) {
return thing[prop as keyof typeof thing]; // assert
}
return undefined as IdxUnion<U, P>; // assert
if(typeof thing==“object”&&prop in thing){
返回thing[prop as key of typeof thing];//断言
}
返回未定义的IdxUnion;//断言
不管怎样,希望这有帮助,祝你好运
感谢@jcalz提供的详细答案,并指出我的实现中缺少了一些键,如toFixed
。完全忘记了它们!
if (typeof thing === "object" && prop in thing) {
return thing[prop as keyof typeof thing]; // assert
}
return undefined as IdxUnion<U, P>; // assert