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>