typescript-book-chinese icon indicating copy to clipboard operation
typescript-book-chinese copied to clipboard

一些有趣的映射类型

Open jkchao opened this issue 5 years ago • 4 comments

tuple to union

type ElementOf<T> = T extends Array<infer E> ? E : T

type ATuple = ['hello', 'world'];

type ToUnion = ElementOf<ATuple>; // 'hello' | 'world'

另一种方法:

type TTuple = [string, number];
type Res = TTuple[number];  // string | number

jkchao avatar Mar 10 '19 09:03 jkchao

让指定的 key 可选:

type MakeKeyOptional<T extends Object, K extends keyof T> = {
  [C in Exclude<keyof T, K>]: T[C]
} & { [D in K]?: T[D] };

interface Options {
  AA: string;
  BB: number;
  CC: boolean;
}

type Test = MakeKeyOptional<Options, 'AA'>;

// {
//   AA?: string;
//   BB: number;
//   CC: boolean;
// }

你也可以让 除了指定的 key,其他都可选。在这里不扩展了。

jkchao avatar Mar 10 '19 09:03 jkchao

A | B 得到 A & B

type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

type Inter = UnionToIntersection<string | number> // string & number

可以用来实现 mixin(来自知乎):

type Ctor<T> = { new(...args: any[]): T}
declare function mixin<T extends Ctor<any>[]>(...traits: T):
    Ctor<UnionToIntersection<InstanceType<T[number]>>>

class Flyable { 
    fly() { }
}
class Walkable {
    walk() {}
}

class Mixed extends mixin(Flyable, Walkable) {
    test() {
        this.fly() // ok
        this.walk() // ok
    }
}

jkchao avatar Mar 11 '19 09:03 jkchao

使用条件类型推断出元组类型的成员:

type GetArrayMembers<T> = T extends {[index in keyof T]: infer V } ? V : never
const example = [1, 2, 3] as const;
type Members = GetArrayMembers<typeof example>; // 1, 2, 3

jkchao avatar Jul 07 '19 02:07 jkchao

让指定的 key 可选:

type MakeKeyOptional<T extends Object, K extends keyof T> = {
  [C in Exclude<keyof T, K>]: T[C]
} & { [D in K]?: T[D] };

interface Options {
  AA: string;
  BB: number;
  CC: boolean;
}

type Test = MakeKeyOptional<Options, 'AA'>
interface Options {
  AA: string;
  BB: number;
  CC: boolean;
}

type Test = MakeKeyOptional<Options, 'AA'>;

// {
//   AA?: string;
//   BB: number;
//   CC: boolean;
// }

你也可以让 除了指定的 key,其他都可选。在这里不扩展了。

这会更改原类型中其它key的属性。如下应该更好

type PartialSome<T, K extends keyof T> = {
  [P in K]?: T[P];
} &
  Omit<T, K>;

Dcatfly avatar Mar 08 '20 12:03 Dcatfly