泛型数组中的空对象打破类型传递?

时间:2018-01-19 22:53:15

标签: typescript typescript2.6

我正在尝试创建一个泛型函数,该函数返回数组中的随机项,并使用Typescript 2.6.2正确转发类型信息。

function sample<T>(array: T[]) : T {
  const index = Math.floor(Math.random() * array.length);
  return array[index];
}

const obj1 = sample([1, 'a', Symbol('sym')]);
// const obj1: number | string | symbol

const obj2 = sample([1, 'a', Symbol('sym'), {}]);
// const obj2: {}

const obj3 = sample([1, 'a', Symbol('sym'), {a: 'a'}]);
// const obj3: number | string | symbol | {a: string}

obj1obj3的类型签名很好,但由于某种原因,第二个示例中的空对象会导致obj2的签名被{}替换

  1. 您能解释为什么obj2的签名变为{}
  2. 有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

在推断类型时,TypeScript会尝试查找表达式的最低公共子类型,通常是这样 导致联合类型。所以如果你有:

compute()

其中a,b和c分别为const x = [a, b, c] AB类型,C的感染类型为x。 这正是A | B | Cobj1所发生的情况。但为什么obj3的类型为obj2

答案是TypeScript具有结构类型,这意味着如果类型A具有类型{}的所有属性,则B的实例可分配给AB表示空对象类型,由于它没有成员,因此任何其他对象类型都是此类型的子类型。因此,感染类型 {}实际上等于number | string | symbol | {}。 (回想一下,当{}A | B的子集时,AB