我正在构建一个类型定义集,该类型定义集将根据用户提供的代表其“状态”模型的类型进行操作。
我需要做的一件事情就是缩小模型的类型,因为我产生了使用并暴露给它们的新类型。
我在缩小作为索引签名的对象的属性时遇到问题。
例如:
/**
* Picks only the keys of a certain type
* Taken from typelevel-ts
*/
type KeysOfType<A extends object, B> = {
[K in keyof A]-?: A[K] extends B ? K : never;
}[keyof A];
interface Address {
street: string;
postCode: string;
}
interface Person {
// I'd like to narrow to this property
favouriteNumbers: {
[id: string]: number;
};
name: string;
address: Address;
}
type PersonIndexSignatures = Pick<
Person,
KeysOfType<Person, { [key: string]: any; }>
>;
type PersonIndexSignaturesKeys = keyof PersonIndexSignatures;
// "favouriteNumbers" | "address"
正如您在上面看到的,我尝试根据Person
缩小{ [key: string]: any; }
的同时产生了favouriteNumbers
和address
键。
我有什么技巧可以将类型缩小为favouriteNumbers
吗?
答案 0 :(得分:1)
这里是一种方法:
首先,我们如何分辨Person["favouriteNumbers"]
和Person["address"]
之间的区别?
这看起来很有希望:
type A = keyof Person["favouriteNumbers"];
// string | number
type B = keyof Person["address"];
// "street" | "postcode"
string
扩展了A
,但没有扩展B
:
type A = string extends keyof Person["favouriteNumbers"] ? true : false;
// true
type B = string extends keyof Person["address"] ? true : false;
// false
我们可以将其签入您的KeysOfType
(您可能可以清理):
type KeysOfType<A extends object, B extends { [key: string]: any }> = {
[K in keyof A]: A[K] extends B ? string extends keyof A[K] ? K : never : never;
}[keyof A];
然后:
type PersonIndexSignaturesKeys = keyof PersonIndexSignatures;
// "favouriteNumbers"