簡體   English   中英

打字稿將函數參數與類型映射的鍵和值匹配

[英]Typescript match function arguments to key and value of a type map

我有一個非常簡單的案例,但我在 Typescript 打字方面的經驗有限,我似乎無法解決這個看似簡單的案例。

我有一個類型映射,例如這樣:

interface KeyValueMap {
  key: 'value';
  foo: 'bar';
}

現在我想將函數的第一個和第二個參數輸入到上面映射的鍵和值中

const test = <K extends keyof KeyValueMap>(key: K, value: KeyValueMap[K]) => {
  switch (key) {
    case 'key':
      return value; // currently getting "KeyValueMap[K]" expecting "value"
    case 'foo':
      return value; // currently getting "KeyValueMap[K]" expecting "bar"
  }
};

我試圖搜索一個類似的案例,但似乎我的谷歌壞了......所以如果這樣的例子已經存在於 Stackoverflow 上,那么標記為重復時不會受到冒犯。

更新

在@ShivamSingla 在我的問題下發表評論后,我意識到我的問題可能不夠清楚。 我對函數的返回值不感興趣,但已經希望在實際函數邏輯中(在 switch-case 中)識別類型。 我將更改示例以使其更清楚:

interface KeyObjectMap {
  foo: {
    key1: 'value1';
  };
  bar: {
    key2: 'value2';
  };
}

const test = <K extends keyof KeyObjectMap>(key: K, value: KeyObjectMap[K]) => {
  switch (key) {
    case 'foo':
      return value.key1; // property 'key1' does not exist on 'KeyObjectMap[K]'
    case 'bar':
      return value.key2; // property 'key2' does not exist on 'KeyObjectMap[K]'
  }
};

在這里你可以找到一個帶有這個例子的游樂場

由於keyvalue沒有關聯,因此可以在 switch case 之前重新分配 value。 這就是錯誤的原因。 請參閱答案以更好地理解。

interface KeyObjectMap {
  foo: {
    key1: 'value1';
  };
  bar: {
    key2: 'value2';
  };
}

type K1 = keyof KeyObjectMap

const test = <K extends K1 = K1>(key: K, value: KeyObjectMap[K]) => {
  // error here, 'key2' is missing
  value = {
    key1: 'value1',
  }

  // value is actually intersection, subtype `KeyObjectMap` actually
  value = {
    key1: 'value1',
    key2: 'value2',
  }

  // since `key` and `value` are not associated, value can be re-assigned
  // before switch case. That's why the error

  switch (key) {
    case 'foo':
      return value.key1; // property 'key1' does not exist on 'KeyObjectMap[K]'
    case 'bar':
      return value.key2; // property 'key2' does not exist on 'KeyObjectMap[K]'
  }
};

操場

可能的解決方案

interface KeyObjectMap {
  foo: {
    key1: 'value1';
  };
  bar: {
    key2: 'value2';
  };
}

const test = <O extends Partial<KeyObjectMap>>(obj: O) => {
  if (obj.foo) {
    return obj.foo.key1
  }

  if (obj.bar) {
    return obj.bar.key2
  }

  return undefined
};

// calling
const c = test({foo: {key1: 'value1'}})

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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