# 条件类型(Conditional Types) (opens new window)

简单实例

interface Animal {
  live(): void;
}
interface Dog extends Animal {
  woof(): void;
}

type Example1 = Dog extends Animal ? number : string;

type Example2 = RegExp extends Animal ? number : string;
1
2
3
4
5
6
7
8
9
10

# 条件类型与泛型

不好的写法

interface IdLabel {
  id: number /* some fields */;
}
interface NameLabel {
  name: string /* other fields */;
}

function createLabel(id: number): IdLabel;
function createLabel(name: string): NameLabel;
function createLabel(nameOrId: string | number): IdLabel | NameLabel;
function createLabel(nameOrId: string | number): IdLabel | NameLabel {
  throw "unimplemented";
}
1
2
3
4
5
6
7
8
9
10
11
12
13

好的写法

type NameOrId<T extends number | string> = T extends number
  ? IdLabel
  : NameLabel;


function createLabel<T extends number | string>(idOrName: T): NameOrId<T> {
  throw "unimplemented";
}

let a = createLabel("typescript");
   

let b = createLabel(2.8);
   

let c = createLabel(Math.random() ? "hello" : 42);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 条件断言

type MessageOf<T> = T extends { message: unknown } ? T["message"] : never;

interface Email {
  message: string;
}

interface Dog {
  bark(): void;
}

type EmailMessageContents = MessageOf<Email>;
              
type DogMessageContents = MessageOf<Dog>;
             

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type Flatten<T> = T extends any[] ? T[number] : T;

// Extracts out the element type.
type Str = Flatten<string[]>;

// Leaves the type alone.
type Num = Flatten<number>;
1
2
3
4
5
6
7