Typescript 动态修改/筛选类型以创建新类型
给定一种类型,例如:Typescript 动态修改/筛选类型以创建新类型,typescript,Typescript,给定一种类型,例如: type PromiseFunc = () => Promise<unknown>; type A = { key1: string; key2: string; key3: PromiseFunc; key4: string; key5: PromiseFunc; key6: SomeOtherType1[]; key7: SomeOtherType2[]; key8: string; key9: PromiseFun
type PromiseFunc = () => Promise<unknown>;
type A = {
key1: string;
key2: string;
key3: PromiseFunc;
key4: string;
key5: PromiseFunc;
key6: SomeOtherType1[];
key7: SomeOtherType2[];
key8: string;
key9: PromiseFunc;
// ...
};
type PromiseFunc=()=>Promise;
A型={
键1:字符串;
键2:字符串;
关键3:承诺;
键4:字符串;
关键5:承诺功能;
键6:SomeOtherType1[];
键7:其他类型2[];
键8:字符串;
关键9:承诺功能;
// ...
};
给定上述类型,我想创建一个新类型,B
,这样:
中类型为A
的所有键在string
B
中类型为A
的所有键在PromiseFunc
B
中属于数组类型的所有键都被排除在A
B
A
,但我想找到一种方法将它们转换为B
等类型。我不控制A
类型的生成
编辑:
链接到另一个解决方案:好吧,我知道了如何做到这一点,我确信有一种更优化的方式来组合这些类型转换,但这就是我目前所拥有的,它可以工作:
type PromiseFunc = () => Promise<unknown>;
// A type whose keys we want to drop.
type SomeOtherType1 = {
key1: string[];
};
// Another type whose keys we want to drop.
type SomeOtherType2 = {
key1: number;
};
type A = {
key1: string;
key2: string;
key3: PromiseFunc;
key4: string;
key5: PromiseFunc;
key6: SomeOtherType1[];
key7: SomeOtherType2[];
key8: string;
key9: PromiseFunc;
};
// Start by building a filter type we can call with the types we want
// and converting all other types to a standard type.
type Filter<T, ConditionOne, ConditionTwo> = {
[Key in keyof T]: T[Key] extends ConditionOne
? string
: T[Key] extends ConditionTwo
? string
: number;
};
// Do the conversion to a new type that only has string and number types.
type ConvertedType = Filter<A, string, PromiseFunc>;
// Now that we only have two types we can drop all the types that don't
// match the type we want (which is string), we'll convert all those keys
// to never which will drop them from our new type.
type PickByValueType<T, U> = {
[K in keyof T as K extends K ? (T[K] extends U ? K : never) : never]: T[K];
};
// Generate the final type that is only the keys which are strings.
type FilteredType = PickByValueType<ConvertedType, string>;
关于使用ommit
排除某些类型,已经有几个问题了,但是我找不到很多好的例子可以让您删除不同类型的多个键。我认为这也可以扩展到处理转换,但我想不出如何在三元运算符的约束下进行转换:
...
type GrabTypesAndConvertOne<T, U, TypeToConvert> = {
[K in keyof T as K extends K
? T[K] extends U
? K
: T[K] extends TypeToConvert
? K // <- Here is where the type change logic would live
: never
: never]: T[K];
};
type GrabbedTypes = GrabTypesAndConvertOne<A, string, PromiseFunc>
。。。
类型抓取类型和转换类型={
[K在K扩展K时按K键
?T[K]扩展U
K
:T[K]将类型扩展为转换
K//你是否已经考虑使用?类似的问题在这里被问到和回答:谢谢你的回答。我没有看到你在你的推荐中链接到的问题,感谢你发现这一点。而且,是的,我遇到了关于需求2的同样的问题。我不控制类型<代码> A<代码>,但是第二个要求对WO是至关重要的。我正试着去做unfortunately@MatthewHerbst我已经用一个符合所有标准的有效解决方案更新了我的答案,有机会的时候看看。也许你会想出一个更好的方法来优化它。如果你这样做了,请标记我。谢谢!我在我的问题中添加了一个指向typescriptlang.org游乐场的链接,其中有一个朋友和我的另一个解决方案想出了(链接太长,不能放在这个评论中)感谢操场链接。这也是一个很好的解决方案。不幸的是,任何一个仍然感觉很混乱。
...
type GrabTypesAndConvertOne<T, U, TypeToConvert> = {
[K in keyof T as K extends K
? T[K] extends U
? K
: T[K] extends TypeToConvert
? K // <- Here is where the type change logic would live
: never
: never]: T[K];
};
type GrabbedTypes = GrabTypesAndConvertOne<A, string, PromiseFunc>