typescript 数组类型和常规对象类型的交集是什么?

bhmjp9jg  于 2023-06-30  发布在  TypeScript
关注(0)|答案(2)|浏览(147)

我在TypeScript 5.1.3中有一个简单的片段,我试图弄清楚unknown[] & A类型的对象是什么样子的。

interface A {
    text: string
}

type AB = unknown[] & A

let a: AB = [{text: "ASDF"}]

console.log(a)

就目前情况来看,我得到一个错误

Type '{ text: string; }[]' is not assignable to type 'AB'.
  Property 'text' is missing in type '{ text: string; }[]' but required in type 'A'.(2322)

有人知道这种类型的对象应该是什么样子的吗?

jgovgodb

jgovgodb1#

你想知道什么值满足AB,定义如下:

interface A {
    text: string
}

type AB = unknown[] & A;

首先,unknown[]表示未知类型的元素数组。A表示具有string类型的属性text的对象。
AB是通过交叉这些类型创建的。这将创建一个可分配给两个相交类型的新类型:它是满足那些类型的值集合的交集。因此,满足此类型的值是具有string类型的额外属性text的数组。
这可以用类型安全的方式创建,如下所示:

interface A {
  text: string
}

type AB = unknown[] & A

const arr = [1, 2, 3]

const result: AB = Object.assign(arr, { text: "Some text" })

TS Playground
顺便说一句
如果你想知道如何创建一个“目标”类型与数组的 element 类型相交的类型,你可以使用下面的generic type。它接受一个数组类型,并生成一个新的数组类型,其中元素类型与给定的目标类型相交。
也就是说,您可以使用它将{ name: string }[]{ text: string }转换为{ name: string; text: string}[]

interface A {
  text: string
}

type MyArray = { name: string }[]

type IntersectArrayElements<A, T> = A extends (infer Element)[]
  ? (Element & T)[]
  : never

type IntersectedArray = IntersectArrayElements<MyArray, A>
//   ^? ({ name: string; } & A)[]
//    = { name: string; text: string; }[]

TS Playground

5kgi1eie

5kgi1eie2#

我认为答案在于A不需要约束来自unknown[]的字段。text字段不在TypeScript数组中,所以它不能真正相交。
就目前而言,没有对象可以是AB类型,但如果A要扩展空对象{}或成为另一种类型的数组(例如,type A = {text: string}[])这将工作得很好。

相关问题