type TypeOfOptions = typeof options[number] // (string | number)[]
type IsTypeOfOptionsSubsetOfSomeTuple =
TypeOfOptions extends SomeTuple ? true : false // false is not assignable to SomeTuple
这意味着TypeOfOptions 只是比SomeTuple 更通用的类型,自然不能用作SomeTuple,这正是您出现错误的原因。你想要[string, number]你通过自动推理得到(string | number)[],显然不一样。
为什么它更通用,因为 TS 类型推断就是这样工作的,我们可以通过 as 或 : 将我们的类型断言为更具体来更改行为,或者创建值构造函数来执行此操作。
以下几个可能的选项如何更改初始推理:
// value constructor
const makeOptions = (...a: SomeTuple[]): SomeTuple[] => a
const options1 = makeOptions(
['first', 1],
['second', 2],
) // a is SomeTuple[]
// using :
const options2: SomeTuple[] = [
['first', 1],
['second', 2],
];
// using as
const options3 = [
['first', 1],
['second', 2],
] as SomeTuple[]
foo(options1) // ok
foo(options2) // ok
foo(options3) // ok
关于评论中问题的附加说明。一般SomeTuple类型是TypeOfOptions类型的规范,这意味着如果你有TypeOfOptions的值,它也可以是SomeTuple,但不是必须的。让我们检查一下这种关系是否正确:
type IsSomeTupleSubsetOfTypeOfOptions = SomeTuple extends TypeOfOptions ? true : false // true
所以是的,SomeTuple 是 TypeOfOptions 的特定变体。这意味着我们可以将TypeOfOptions 的类型断言为SomeTuple,表示我们正在缩小到这种特定情况。但如果我们这样做 - TS 将立即验证缩小类型的值,如果匹配,则类型断言成功。