想象一下這個類:
class Person {
name = "Ann";
sleep() { /*...*/ }
eat() { /*...*/ }
}
現在我想創建一個只提取方法的型別:
// should work:
const personMethods: MethodsOf<Person> = { sleep() {}, eat() {} };
const names: keyof MethodsOf<Person>[] = ['sleep', 'eat'];
// should fail:
const personMethods: MethodsOf<Person> = { notAPersonMethod() {} };
const names: keyof MethodsOf<Person>[] = ['not', 'existing', 'methods'];
我在打字稿檔案中找不到任何內容,到目前為止我的嘗試都失敗了。我試過:
type MethodKeys<
Type extends object,
Key extends keyof Type,
> = keyof Record<Type[Key] extends AnyFn ? Key : never, any>;
type Methods<Type extends object> = {
[Property in MethodKeys<Type, keyof Type>]: Type[Property];
};
const test: MethodKeys<Person> = 'name'; // works, but shouldn't :(
const test2: Partial<Methods<Person>> = { name: 'Ann' }, // works too :/
謝謝你的幫助!
uj5u.com熱心網友回復:
除了@Chase 的解決方案之外,您還可以使用分布式條件型別來過濾掉具有函式值的鍵:
type MethodHelper<T, K extends keyof T> = K extends any
? T[K] extends Function ? K
: never : never;
然后用它來實作MethodKeys和Methods:
type MethodKeys<T> = MethodHelper<T, keyof T>;
type Methods<T> = {
[K in MethodKeys<T>]: T[K]
};
const test: MethodKeys<Person> = 'name'; // doesn't work
const test2: MethodKeys<Person> = 'sleep'; // does work
const test3: Partial<Methods<Person>> = { name: 'Ann' }; // doesn't work
const test4: Partial<Methods<Person>> = { sleep() {} }; // does work
游樂場鏈接
uj5u.com熱心網友回復:
您所需要的只是一個型別,它可以為您回傳給定類/介面的方法名稱。您可以使用映射型別來創建物件型別,其中每個值代表每個方法名稱。然后,您可以索引該物件型別以獲取其值型別 - 這將產生所有方法名稱的聯合。
type MethodKeys<T> = {
[K in keyof T]: T[K] extends (...x: any) => any ? K : never;
}[keyof T]
現在,您可以使用Pick從您的類/介面中選擇這些方法鍵。
type MethodsOf<T> = Pick<T, MethodKeys<T>>;
并且您給定的測驗用例可以正常作業-
// works
const personMethods: MethodsOf<Person> = { sleep() {}, eat() {} };
const names: Array<keyof MethodsOf<Person>> = ['sleep', 'eat'];
const personMethods1: MethodsOf<Person> = { notAPersonMethod() {} };
// ^ Type '{ notAPersonMethod(): void; }' is not assignable to type 'MethodsOf<Person>'.
const names1: Array<keyof MethodsOf<Person>> = ['not', 'existing', 'methods'];
// ^ Type '"not"' is not assignable to type 'MethodKeys<Person>'.
// ...and more
在操場上檢查一下。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/350681.html
