繁体   English   中英

如何创建一个泛型 typescript 类型 function 并从参数类型推断出返回类型?

[英]How do I make a generic typescript type function that has the return type inferred from the argument type?

我想将此模式用于许多参数 object 类型,并且 function 的返回类型与 object 类型的值相同

type IntentColorCategory = 'brand' | 'neutral' | 'semantic'
type IntentColor = 'primary' | 'secondary' | 'neutral' | 'error' | 'success'

// Understandably this doesn't work - intention is to have a function that
// has a return type corresponding to the value of the argument object
// values.
const getByIntentColorCategory<T extends any> = ({
  brand,
  neutral,
  semantic
}: Record<IntentColorCategory, T>) => (intent: IntentColor): T => {
  switch (intent) {
    case 'primary':
    case 'secondary':
      return brand;
    case 'neutral':
      return neutral;
    case 'error':
    case 'success':
    default:
      return semantic;
  }
}


// E.g.
getByIntentColorCategory<number>({ brand: 1, semantic: 2, neutral: 3 })
// I want to specify the object must have number values when used here and
//that the return type is a number

getByIntentColorCategory<string>({ brand: 'a', semantic: 'b', neutral: 'c' })
// I want to specify the object must have strings when used here and that
// the return type is a string

如果我正确理解你的问题 - 我认为你只是在你放置通用参数的地方。 它应该是 go 旁边的 arguments(在 function 一侧,而不是赋值一侧)。

type IntentColorCategory = 'brand' | 'neutral' | 'semantic'
type IntentColor = 'primary' | 'secondary' | 'neutral' | 'error' | 'success'

const getByIntentColorCategory = <T extends any>({
  brand,
  neutral,
  semantic
}: Record<IntentColorCategory, T>) => (intent: IntentColor): T => {
  switch (intent) {
    case 'primary':
    case 'secondary':
      return brand;
    case 'neutral':
      return neutral;
    case 'error':
    case 'success':
    default:
      return semantic;
  }
}

然后,您甚至可以在使用 function 时删除显式类型参数:

在此处输入图像描述

感谢@mbdavis,他的解决方案工作正常:

type IntentColorCategory = 'brand' | 'neutral' | 'semantic'
type IntentColor = 'primary' | 'secondary' | 'neutral' | 'error' | 'success'

const getByIntentColorCategory = <T extends any>({
  brand,
  neutral,
  semantic
}: Record<IntentColorCategory, T>) => (intent: IntentColor): T => {
  switch (intent) {
    case 'primary':
    case 'secondary':
      return brand;
    case 'neutral':
      return neutral;
    case 'error':
    case 'success':
    default:
      return semantic;
  }
}

type NumberIntents = Record<IntentColorCategory, number>
type StringIntents = Record<IntentColorCategory, string>

const numberIntents: NumberIntents = {
  brand: 1,
  neutral: 2,
  semantic: 3,
}

const stringIntents: StringIntents = {
  brand: 'a',
  neutral: 'b',
  semantic: 'c',
}

getByIntentColorCategory(numberIntents); // returns number
getByIntentColorCategory(stringIntents); // returns string

TS 游乐场链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM