打字稿选择错误的类型

Typescript picking wrong type

我很抱歉问了一个无聊的问题,但我正在学习打字稿,遇到了我无法克服的情况。

我用Victory charts where component accepts to pass data of type DomainPropType. So I downloaded and installed @types/victory用这个类型

从那时起,就可以将数据传递给组件了。

但是...

// unimportant code was striped out

import { DomainPropType } from 'victory';

class Charts extends Component<Props, State> {
    private entireDomain: DomainPropType;

    public constructor(props: Props) {
        super(props);

        this.entireDomain = this.getEntireDomain();
        console.log(this.entireDomain);    // <= got {x:[82800000, 1206000000] ,y: [0, 1]}
        console.log(this.entireDomain.x);  // <= got 'Property 'x' does not exist on type 'DomainPropType'.
    }


    public getEntireDomain(): DomainPropType {
        const xValues = this.entireDataSet.map((item: DataSetItem) => item.x);
        const yValues = this.entireDataSet.map((item: DataSetItem) => item.y);

        return {
            x: [xValues[0].valueOf(), xValues[xValues.length - 1].valueOf()],
            y: [Math.min(...yValues), Math.max(...yValues)]
        };
    }
}


在第一个 console.log 中可以清楚地看到 entireDomain 是具有键 x 的对象。那么为什么在第二个 console.log typeScript 中抛出以下错误?

Property 'x' does not exist on type 'DomainPropType'.
Property 'x' does not exist on type '[number, number]'.

好的,它也说 [number, number]。然而,这就是类型的样子:

如果我没理解错的话……DomainPropType 也可以是 { x?: DomainTuple; y: DomainTuple; } 类型。那为什么 typeScript 选错了验证呢?请有人给我解释一下。

你可以像那样转换你的数组:

return {
            x: [xValues[0].valueOf(), xValues[xValues.length - 1].valueOf()],
            y: [Math.min(...yValues), Math.max(...yValues)]
        } as DomainPropType;

您的错误可能与您在屏幕截图中看到的可为空的 x 或 y 相关联。

当您将类型添加到函数 argument/constructor 时,打字稿假定您代码中的其他地方,有人可能会用这些参数调用 function/constructor。

因此,即使您只使用 class 一次,并且在这种特定情况下,您传递了一个具有 xy 属性的对象,以后您仍然有可能也使用 class 并使用 [number, number][Date, Date] 格式。

为避免这种情况,您有 2 个选择:

  1. 不要使用 DomainPropType 作为参数类型,而是仅使用您实际想要使用的特定类型。
  2. 在您的构造函数中,正确处理 [number, number][Date, Date] 情况。

如果您从未打算使用 [Date, Date][number, number] 调用此对象,选择选项 1 可能是最简单的。

我认为适合您的情况的更具体类型的示例:

type MyDomainPropType = {
   x: DomainTuple,
   y?: DomainTuple
}