Implement the built-in Pick<T, K> generic without using it.
Constructs a type by picking the set of properties K from T
實現內建的 Pick<T, K> 泛型,而不使用它。
通過從 T 中選擇屬性 K 的集合來構造一個型別。
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyPick<Todo, 'title' | 'completed'>
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
}
接下來,你的任務是讓下面的type cases測試通過:
type cases = [
Expect<Equal<Expected1, MyPick<Todo, 'title'>>>,
Expect<Equal<Expected2, MyPick<Todo, 'title' | 'completed'>>>,
]
interface Todo {
title: string
description: string
completed: boolean
}
interface Expected1 {
title: string
}
interface Expected2 {
title: string
completed: boolean
}
在這一關中,我們需要:
我們會用到:
使用 keyof 操作符獲取 T 的所有鍵。
過濾出 K 中的鍵並構造新的型別。
type MyPick<T, K extends keyof T> = {
[P in K]: T[P];
};
細節分析:
K extends keyof T
:K
is a union of keys from T
.T
: This operator produces a union type of all the keys of T
. For example, if T
is { a: number; b: string }, then keyof T
is 'a' | 'b'.K extends keyof T
: This means that K must be a union of keys that are valid within T
. If T
has keys 'a' and 'b', then K can only be 'a' | 'b'
. This ensures type safety by preventing any invalid keys from being used.[P in K]: T[P]
:T
but only for the keys specified in K
.[P in K]
: This is a mapped type syntax. It iterates over each key P
in the union K
.T[P]
: For each key P
, it assigns the corresponding property type from T
. In other words, for each key in K
, the new type will have the same property type as in T
.Pick<T, K>:
T
中選擇指定鍵 K
的屬性來構造新型別。interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, 'title' | 'completed'>;
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
};
extends:
interface Base {
id: number; // 基礎型別的屬性
}
interface Extended extends Base {
name: string; // 繼承並新增屬性
}
const obj: Extended = { id: 1, name: 'Alice' };
keyof:
T
中所有鍵的聯合型別。interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoKeys = keyof Todo; // 'title' | 'description' | 'completed'
聯合型別(Union of Keys):
type KeyUnion = 'title' | 'completed'; // 聯合型別,可以是 'title' 或 'completed'
映射型別(Mapped Types):
in
操作符來遍歷原始型別的鍵。type MappedType<T> = {
[K in keyof T]: T[K];
};
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoCopy = MappedType<Todo>; // 與 Todo 相同的型別
in
操作符:
type MyPick<T, K extends keyof T> = {
[P in K]: T[P];
};
// `[P in K]` 用來遍歷 K 中的每個鍵 P
type TodoPreview = MyPick<Todo, 'title' | 'completed'>;
Subset:
interface Todo {
title: string;
description: string;
completed: boolean;
}
// 'title' | 'completed' 是 Todo 鍵的子集
type TodoSubset = Pick<Todo, 'title' | 'completed'>;
本次介紹了 Pick
的實作,許多關鍵字會在第7關進一步詳細介紹和補充更多例子!下一關會挑戰Readonly
,期待再相見!