通用、联合和扩展。打字稿

时间:2021-04-07 07:40:50

标签: typescript typescript-typings typescript-generics

我有一堂课RawTemplate

export type TestUnion = 'test1' | 'test2';
export class RawTemplate {
  someProperty: Record<TestUnion, Record<string, string>>;
}

并且我创建了扩展 Raw

的新类 RawTemplate
export class Raw extends RawTemplate {
  someProperty: {
    test1: { name1: 'name'; name2: 'name' };
    test2: { name3: 'name' };
  };
}

然后我创建泛型类型 Generic 和类型 Target

export type Key<T extends RawTemplate> = keyof T['someProperty'][TestUnion];

export type Generic<T extends RawTemplate> = Record<Key<T>, string>;

export type Target = Generic<Raw>;

我想得到这样的 Target 类型:{ name1: string; name2: string; name3: string } 但我得到了 关注类型:{}

如果我像这样重写我的类型:

export type Key<T extends RawTemplate> = keyof T['someProperty']['test1'];

export type Generic<T extends RawTemplate> = Record<Key<T>, string>;

export type Target = Generic<Raw>;

我得到以下 Target 类型:{ name1: string; name2: string } 几乎是我想要的。

或者我可以像这样重写我的类型:

export type Key<T extends RawTemplate> = keyof T['someProperty']['test1' | 'test2'];

export type Generic<T extends RawTemplate> = Record<Key<T>, string>;

export type Target = Generic<Raw>;

但我再次得到以下 Target 类型:{}

我发现的唯一可行案例:

export type Key1<T extends RawTemplate> = keyof T['someProperty']['test1'];

export type Key2<T extends RawTemplate> = keyof T['someProperty']['test2'];

export type Generic<T extends RawTemplate> = Record<Key1<T>, string> | Record<Key2<T>, string>;

export type Target = Generic<Raw>;

我怎样才能更正写的类型?我将缩放 TestUnion 类型并且我不想每次都重写我的 Generic 类型。

1 个答案:

答案 0 :(得分:0)

您无法使用元组 (|) 获取对象的属性类型。

// type Target = never
type Target = keyof Raw['someProperty']['test1' | 'test2']

您将不得不对键进行元组。

export type Generic<T extends RawTemplate> = Record<Key<T, 'test1'> | Key<T, 'test2'>, string>;

// type Target = {
//     name1: string;
//     name2: string;
//     name3: string;
// }
export type Target = Generic<Raw>;

或者,连接对象并在其上使用 keyof

// type Target = {
//     name1: string;
//     name2: string;
//     name3: string;
// }
export type Target = { [key in keyof (Raw['someProperty']['test1'] & Raw['someProperty']['test2'])]: string };