有时为了简化具有复杂输入的函数签名,我们会定义一个“已知”复杂输入的集合,每个输入都与一个令牌相关联,并允许用户提供令牌。
我的函数适用于元组(这里简化为 3 元素元组),最初它没有任何编译器错误:
const TUPLE_LENGTH = 3
type Tuple = readonly [unknown, unknown, unknown]
function fn(tuple: Tuple): void {
if (tuple.length !== TUPLE_LENGTH) {
throw new Error(`Expected ${TUPLE_LENGTH} items, instead got ${tuple.length}`)
}
}
尝试一下。
…但是在添加“已知”输入后,开始出现编译器错误:
const TUPLE_LENGTH = 3
type Tuple = readonly [unknown, unknown, unknown]
const knownTuples = {
foo: [1, 2, 3],
bar: ['a', 'b', 'c'],
baz: [true, false, null],
} satisfies Readonly<Record<string, Tuple>>
type TupleName = keyof typeof knownTuples
function fn(tuple: Tuple | TupleName): void {
if (typeof tuple === 'string') {
tuple = knownTuples[tuple]
}
if (tuple.length !== TUPLE_LENGTH) {
throw new Error(`Expected ${TUPLE_LENGTH} items, instead got ${tuple.length}`)
// ^^^^^^
// Error: Property 'length' does not exist on type 'never'
}
}
尝试一下。
由于某种原因,if (tuple.length !== TUPLE_LENGTH)
在第一种情况下,它是 ,tuple: Tuple
但在第二种情况下,它缩小到tuple: never
。这是为什么?