gpt4 book ai didi

typescript - 为什么这种类型的联合在 typescript 中被解析为一个交集?

转载 作者:行者123 更新时间:2023-12-05 04:33:51 29 4
gpt4 key购买 nike

我无法理解我遇到的 typescript 错误背后的机制 - 我确信有一些基本的东西在我头顶上飞过时发出“嗖”的声音。

我只找到了 this关于该主题的问题,但虽然错误看起来相同,但设置对我来说似乎完全不同。

这是我引用的定义,为简洁起见。

type ApexAxisChartSeries = {
// ...
data:
| (number | null)[]
| {
x: any;
y: any;
// ...
}[]
| [number, number | null][]
| [number, (number | null)[]][];
}[]

这是一个错误的函数,它接受一个 {x:number, y:number} 数组。

function composeSeries(input: { x: number; y: number }[]) {
const series: ApexAxisChartSeries = [
{ name: "A", data: [] },
{ name: "B", data: [] },
];

input.forEach((datum) => {
series[0].data.push(datum); // <-- This line right here gives the error.
});

return series;
}

现在,让我感到困惑的是,根据类型定义,我希望 {x:number, y:number} 对象是 data 的完全有效元素>,但是 typescript 提示说

Argument of type '{ x: number; y: number; }' is not assignable to parameter of type number & { x: any; y: any; fillColor?: string | undefined; strokeColor?: string | undefined; meta?: any; goals?: any; } & [number, number | null] & [number, (number | null)[]]'.

Type '{ x: number; y: number; }' is not assignable to type 'number'.

我在这里想,如果类型定义使用联合,错误中的交集来自哪里

作为附加上下文:

  1. 不仅仅是对象出错了。如果我使用 [x,y] 元组或只是一个数字数组,编译器仍然会活跃起来
  2. 我正在使用 TS 4.5.4
  3. 我非常肯定此代码中存在问题:TS playground 给出了相同的错误

作为引用,这是完整的类型定义:

type ApexAxisChartSeries = {
name?: string
type?: string
color?: string
data:
| (number | null)[]
| {
x: any;
y: any;
fillColor?: string;
strokeColor?: string;
meta?: any;
goals?: any;
}[]
| [number, number | null][]
| [number, (number | null)[]][];
}[]

非常感谢任何澄清!

编辑:可以在 TS Playground 上找到错误示例 here ,由@jcalz 提供

最佳答案

(T | U)[]T[] | 是有区别的你[]。第一种,每个数组元素可以是 TU 类型。在第二个(与您的情况相对应)中,数组只能包含任一类型的元素。

您必须问自己的问题是:当 TypeScript 不知道变量是哪种类型的数组时,它如何知道允许哪些元素?

const myArray: string[] | number[] = [];
myArray.push(5); // Argument of type 'number' is not assignable to parameter of type 'never'.

以上面的例子为例。无论如何,TypeScript 都会抛出错误,因为无论您向该数组推送什么,都不会符合其中一种可能的类型。

好消息是 TypeScript 编译器很聪明,并且在您的情况下发现可以派生出符合所有可能条件的类型。该类型恰好是所有可能的元素类型的交集,是满足要求的最基本类型。

您的选择是要么使数组允许任何可能的类型,要么使该系列成为扩展任何一种类型的泛型。

选项A:数组元素可以是多种类型之一

type ApexAxisChartSeries = {
name: string,
data:
(number
| null
| { x: any; y: any; }
| [number, number | null]
| [number, (number | null)[]]
)[]
};

选项 B:泛型类型参数可以是多种类型之一

type ChartDataType = (number | null)
| { x: any; y: any; }
| [number, number | null]
| [number, (number | null)[]];

type ApexAxisChartSeries<T extends ChartDataType> = {
name: string,
data: T[]
}[];

function composeSeries<T extends ChartDataType>(input: T[]) {
const series: ApexAxisChartSeries<T> = [
{ name: "A", data: [] },
{ name: "B", data: [] },
];

input.forEach((datum) => {
const index = (true) ? 0 : 1;
series[index].data.push(datum);
});

return series;
}

composeSeries([{ x:1, y: 1}]); // returns { name, data: { x, y }[] }[]

关于typescript - 为什么这种类型的联合在 typescript 中被解析为一个交集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71313168/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com