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,期待再相見!