将元组分解为另一个元组类型不匹配

时间:2019-03-05 23:48:52

标签: typescript

据我所知,以下功能似乎在输入方面合乎逻辑:

function testFunction<A,B,C,D> (a: A, more: [B, C, D]) : [A,B,C,D] {
    return [a, ...more];
}

相反,打字稿抱怨...more,并出现以下错误:

Type 'B | C | D' is not assignable to type 'B'.
Type 'C' is not assignable to type 'B'.

我是否在这里遗漏了一些东西,或者这是类型检查器中的一个疏忽,可以安全地用return [a, ...more] as [A,B,C,D];强制类型

1 个答案:

答案 0 :(得分:0)

似乎在应用传播运算符时,类型检查器确实确实将元组类型扩展为联合类型。观察:

const foo: [A, B] = ...
const bar = [...foo];    // inferred type (A | B)[]

我不确定这是设计使然还是对当前实现的限制。我希望它实际上是后者,因为任何期望T[]的函数都必须 扩展[A, B](A | B)[]以适合类型参数T

在这种情况下,无法使用[A, B]生成Array.of,因为它的签名是T[] Array.of<T>(...items: T[])

Array.of(a, b);        // Argument of type 'B' is not assignable to parameter of type 'A'.
Array.of<A | B>(a, b); // Fine, but inferred type (A | B)[]
Array.of(...[a, b]);   // Fine, but inferred type (A | B)[]

解决此问题的一种方法是简单地构造不具有传播运算符的结果数组:

function testFunction<A,B,C,D> (a: A, more: [B, C, D]) : [A,B,C,D] {
  return [a, more[0], more[1], more[2]];
}

或者稍微清洁

function testFunction<A,B,C,D> (a: A, [b, c, d]: [B, C, D]) : [A,B,C,D] {
  return [a, b, c, d];
}