我试图找到一种方法来告诉TypeScript的编译器,一个值是(深呼吸)一个通用类型的键,如果将其应用于该类型的对象,它将导致a的属性。具体类型。我知道这句话确实令人困惑,所以这是一个具体的例子。
const obj: T = an object of type T;
const key: KeysMatching<T, U> = a key that matches `typeof T[key] === U`;
const attribute = obj[key];
在这里,我希望attribute
的类型为U
或可分配给类型U
。
我从TypeScript文档中提供的Filter helper中得到了启发,尝试使用this answer中提出的类型似乎很适合我的情况(但显然不是),最后尝试了创建自己的帮助程序,以过滤某些类型的属性:
type KeysMatching<T, U> = T[keyof T] extends U ? keyof T : never;
当前,在我的自定义解决方案中,attribute
的类型为T[T[keyof T] extends U ? keyof T : never]
,并且无法分配给U
。
有没有一种方法可以实现我想做的事情?
我试图给出一个可重现的案例,但是如果您需要更多信息,上下文或实际案例,请随时提问!
在此先感谢任何可能给我一些想法或解决方案的人。
答案 0 :(得分:1)
在条件类型打字稿中使用泛型类型参数时,只要它们中仍然存在未解析的类型参数,就无法对其进行太多推理。这就是为什么从通用类/函数的外部可以按预期运行但在内部仍无法正常运行的情况下,编译器不允许您对此类类型执行很多操作的原因:
type KeysMatching<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
function test<T, K extends KeysMatching<T, string>>(o: T, k: K): T[K] {
let v = o[k];
v.toLowerCase() // error
return v;
}
test({ a: ""}, "a").toLowerCase() // ok from outside
有时您可以通过约束T
而不是K
来解决此问题。
function test<T extends Record<K, string>, K extends PropertyKey>(o: T, k: K): T[K] {
let v = o[k];
v.toLowerCase(); //ok
return v
}
这确实有局限性,因为示例intelisense不会显示K
的建议。