簡體   English   中英

TypeScript:告訴對象它可以擁有哪些鍵和值

[英]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 typeinterface (我們稱之為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回調。

TS 游樂場

// 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM