[英]TypeScript: Tell object which keys and values it can have
我有一個代表某些常量之一的類型。 每種類型還有一個特定的回調函數。
type MyType = 'A' | 'B' | 'C';
// Same for 'B', 'C' etc.
type callbackForA = (result: ResultForA) => void;
ResultForA
是屬於A
的特定對象。
我想為一個對象創建一個 TypeScript type
或interface
(我們稱之為MagicType
),該對象可能對每個MyType
常量都有一個鍵。 這些鍵中的每一個的值都可以是true
(或隱式undefined
因此“可能有” ),或者可能是具有基於類型的特定調用簽名的回調函數。
以下應該是一個有效的MagicType
對象:
const myObject: MagicType = {
'A': true | (result: ResultForA) => void,
'C': true;
}
其中B
未配置, C
不接受回調。
以下應該是MagicType
的無效對象。
const myObject: MagicType = {
'A': true | (result: ResultForB) => void;
'FOO': true
}
因為A
有錯誤的回調函數(result: ResultForB) => void
並且FOO
不是MyType
的有效選項。
你如何實現這樣的類型?
我嘗試過的是像這樣擴展Result
類型:
type CallbackFunctionVariadicAnyReturn = (...args: any[]) => any
interface MagicType extends Record<MyType, true | CallbackFunctionVariadicAnyReturn>;
不幸的是,它既不檢測諸如FOO
多余鍵,也不檢測錯誤的回調函數。
額外的想法/問題:
還有一種方法可以將回調緊密耦合到每個MyType
值嗎? 也許是這樣的元組?
type MyTypePairs = ['A', (result: ResultForA) => void] | ['B', // ...
type MagicType = {
'A': boolean | (result: ResultForA) => void,
'B': undefined,
'C': boolean,
}
這樣做是為三個鍵中的每一個添加類型注釋,並且因為 TS 不允許除列出的鍵之外的任何鍵,您不能執行'FOO'
鍵,並且回調上的注釋意味着您可以不要在 a 上執行(result: ResultForB) => void
回調。
// define your types
type ResultForA = { a: string };
interface ResultCollection {
A: ResultForA; // can use named type alias
B: { b: boolean }; // or simply inline your result types
C: { c: number };
}
// Bonus thought / question:
type ResultFunc<K extends keyof ResultCollection> = (result: ResultCollection[K]) => void;
// Tell object which keys and values it can have
type MagicType = Partial<{[K in keyof ResultCollection]: ResultFunc<K> | boolean}>;
// examples
const good1: MagicType = { // ok
A: true,
B: (r: { b: boolean }) => {
console.log(r);
},
};
const good2: MagicType = { // ok
A: (r: { a: string }) => {},
B: (r: { b: boolean }) => {
console.log(r);
},
C: false
};
const bad1: MagicType = {
Foo: true, // error
}
const bad2: MagicType = {
B: (r: { c: number }) => { // error
console.log('not a good b');
},
};
為此,您需要創建映射數據結構,它將每個允許的鍵映射到某種類型/值。 考慮這個例子:
type MyMap = {
A: "#A",
B: '#B',
C: '#C'
}
type MyType = keyof MyMap
type ResultForA = '#A'
type ResultForB = '#B'
type ResultForC = '#C'
type MagicType<Dict> = {
[Prop in keyof Dict]?: true | ((value: Dict[Prop]) => void)
}
type Result = MagicType<MyMap>
類型MyMap
是一種地圖數據結構,您可能已經猜到了。
MagicType
是在映射類型的幫助下構建的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.