我有两种联合类型(均为字符串文字)和一个硬编码映射对象,该对象将这两种类型相互映射。
type Digit = '1' | '2'
type Alpha = 'a' | 'b'
const map: Record<Digit, Alpha> & Record<Alpha, Digit> = {
'1': 'a',
'2': 'b',
'a': '1',
'b': '2'
}
当再次使用单例值时,硬编码映射会很好用。
let digit: Digit = '1'
let alpha = map[digit] // alpha is inferred as Alpha
let digit2 = map[alpha] // digit2 is inferred as Digit
用函数包装它,然后在数组上进行映射也是可能的。
let digitArr: Digit[] = ['1', '2']
let alphaArr = digitArr.map(d => map[d]) // inferred as Alpha[]
但是当我只想使用一个带有重载的函数来实现双向映射时,即
digitArr.map(mapping) // returns Alpha[]
alphaArr.map(mapping) // returns Digit[]
// where digitArr and alphaArr is deterministically typed as Digit[] and Alpha[]
类型系统抱怨它,我不知道如何使它快乐。
我的函数定义:
function overloadedMapping(digit: Digit): Alpha
function overloadedMapping(alpha: Alpha): Digit
function overloadedMapping(key: Digit | Alpha): Digit | Alpha {
return map[key]
}
此函数也可用于单例值,并且在一种数组上失败。
let d = overloadedMapping('a') // d is of type Digit
let a = overloadedMapping('1') // a is of type Alpha
let arr = alphaArr.map(overloadedMapping) // arr is of type Digit[]. works? why?
let arr2 = digitArr.map(overloadedMapping) // type inference fails!! why?
一个有趣的发现:切换重载声明顺序时,失败的数组映射也会交替出现。
答案 0 :(得分:0)
当重载解析无法使回调与所需的签名匹配时,可以通过显式提供type参数来告诉TypeScript您的意图:
let arr2 = digitArr.map<Alpha>(overloadedMapping)
现在,您的转换将被视为(value: Digit, index: number, array: Digit[]) => Alpha
。
在这种情况下,选择不使用无点样式也将有助于TypeScript匹配重载:
let arr2 = digitArr.map(digit => overloadedMapping(digit))