【问题标题】:Typescript parameters to keys and values from an object来自对象的键和值的打字稿参数
【发布时间】:2022-01-03 02:33:02
【问题描述】:

例子

const food = {
  fruit: ['apples', 'oranges'],
  meat: ['chicken', 'pig']
}

function makeFood(ingredient, category) {
 switch(true) {
   case category === 'fruit' && ingredient === 'apples' {
    // do something
   }
   case category === 'fruit' && ingredient === 'oranges' {
    // do something
   }
   case category === 'meat' && ingredient === 'chicken' {
    // do something
   }
   case category === 'meat' && ingredient === 'pig' {
    // do something
   }
 }
}

输入类别的最佳方式是食物的关键,成分是价值?

目前我在做

function(ingredient, keyof typeof category) {

希望保持两者之间的关系。所以 TS 会根据类别值知道成分类型。

【问题讨论】:

  • 你能提供一个更完整的例子吗?
  • category 是什么? ingredientcategoryfood 有什么关系?
  • 我会马上更新问题
  • 不确定你到底想要什么,但像function f<T extends keyof typeof food>(ingredient: (typeof food)[T][number], category: T) {?请注意,除非您将as const 添加到food 中的数组中,否则它们只是string[]。另请注意,[number] 可能有点快&脏,有alternatives
  • @Norfeldt 不是我的反对票

标签: javascript typescript


【解决方案1】:

你使用打字稿Generics。在此您希望 category 成为通用参数,然后可以使用哪个成分。

您需要在源对象上使用as const(请参阅here)以确保它的特定字符串是其类型的一部分。

const food = {
  fruit: ['apples', 'oranges'],
  meat: ['chicken', 'pig']
} as const // important to add "as const" here

function makeFood<
  K extends keyof typeof food // Generic parameter
>(
  ingredient: typeof food[K][number], // use K to lookup types for ingredient
  category: K // provide the key to to use here as K
) {
 switch(true) {
   case category === 'fruit' && ingredient === 'apples': {
    // do something
   }
   case category === 'fruit' && ingredient === 'oranges': {
    // do something
   }
   case category === 'meat' && ingredient === 'chicken': {
    // do something
   }
   case category === 'meat' && ingredient === 'pig': {
    // do something
   }
 }
}

makeFood('apples', 'fruit')
makeFood('pig', 'fruit') // type error

Playground

【讨论】:

  • 另外很酷的是,它会阻止您在 switch 中使用拼写错误。
  • 非常感谢您这么快的回答
  • 没有泛型的替代方案是function makeFood(ingredient: typeof food[typeof category][number], category: keyof typeof food)
  • 我一直在想一定有一种方法可以使用infer,所以编译器可以推断出在第一个case子句中,成分只能是'apples'|'oranges'
  • @JuanMendes 没有泛型的建议是更好的事件,因为它在 vscode 中自动完成时保持类型之间的关系。如果您将其发布为答案,我将给它投票。
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 2020-05-02
  • 2021-06-28
  • 2021-09-13
相关资源
最近更新 更多