TypeScript 之嵌套数组与深度可选类型

嵌套数组类型

以下类型可用于描述嵌套的数组类型。

1
2
3
4
5
6
7
8
9
10
11
interface DeepArray<T> extends Array<T | DeepArray<T>> {}

const array: DeepArray<string | boolean> = [
'string',
true,
['string'],
[true, ['string']],
[[['string', false, 'string']]],
];

const bArray: DeepArray<string | boolean> = [1]; // Error

数组 – 在 TypeScript 中描述一个深度嵌套的数组

深度可选类型

以下类型可将一个类型的所有属性、子属性转变为 Partial

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends Array<infer U>
? Array<DeepPartial<U>>
: T[P] extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: DeepPartial<T[P]>;
};

interface A {
a: {
a1: {
a2: string;
b2: string;
};
b1: {
a2: number;
b2: Array<number | string>;
};
};
b: string;
c: number[];
}

let t1: DeepPartial<A>;

t1.a.a1.a2; // (property) a2?: string
t1.a.a1.b2; // (property) b2?: string
t1.a.b1.b2; // (property) b2?: (string | number)[]
t1.b; // (property) b?: string
t1.c; // (property) c?: number[]

How to implement TypeScript deep partial mapped type not breaking array properties

注:上述类型中的 extends ... ? ... 可看作类型中的三元表达式。

1
2
3
4
5
6
7
8
9
10
// 若泛型 T 继承于 string,则函数 a 返回的类型为 string,否则为 boolean
function a<T>(arg: T): T extends string ? string : boolean {
// ...
}

interface MyString extends String {}

a('string'); // function a<string>(arg: string): string
a(1); // function a<number>(arg: number): boolean
a('string' as MyString); // function a<MyString>(arg: MyString): boolean
0%