元组的 TypeScript 数组

Del*_*avo 6 arrays types tuples typescript

所以我有这个简单的例子:

type SomeTuple = [string, number];

const foo = (options: SomeTuple[]) => console.log(options);

const options = [
    ['first', 1],
    ['second', 2],
];

const otherOptions: SomeTuple[] = [
    ['first', 1],
    ['second', 2],
];

foo(options); // Error

foo(otherOptions); // OK
Run Code Online (Sandbox Code Playgroud)

基本上没有什么可说的了,我就是不明白为什么 TS 总是在我没有明确提供选项类型的情况下向我显示错误;

操场

感谢您的时间!

Mac*_*ora 5

type TypeOfOptions = typeof options[number] // (string | number)[]
type IsTypeOfOptionsSubsetOfSomeTuple = 
  TypeOfOptions extends SomeTuple ? true : false // false is not assignable to SomeTuple

Run Code Online (Sandbox Code Playgroud)

这意味着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
Run Code Online (Sandbox Code Playgroud)

关于评论中问题的附加说明。通常 typeSomeTuple是type的规范TypeOfOptions,这意味着如果您有值,TypeOfOptions它也可以SomeTuple但不是必须的。让我们检查这种关系是否为真:

type IsSomeTupleSubsetOfTypeOfOptions = SomeTuple extends TypeOfOptions ? true : false // true
Run Code Online (Sandbox Code Playgroud)

所以 yesSomeTupleTypeOfOptions. 这意味着我们可以断言的类型TypeOfOptionsSomeTuple说,我们正在缩小这一具体例。但是如果我们这样做 - TS 将立即验证缩小类型的值,如果匹配,则类型断言成功。