我想将该模式重用于许多参数对象类型,并使函数的返回类型与对象类型的值相同
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
答案 0 :(得分:1)
如果我正确理解了您的问题-我认为您只会受到放置通用参数的位置的困扰。它应该放在参数旁边(在函数侧,而不是在赋值侧)。
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;
}
}
您甚至可以在使用函数时删除显式类型参数:
答案 1 :(得分:0)
感谢@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