打字稿选择错误的类型
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 一次,并且在这种特定情况下,您传递了一个具有 x
和 y
属性的对象,以后您仍然有可能也使用 class 并使用 [number, number]
或 [Date, Date]
格式。
为避免这种情况,您有 2 个选择:
- 不要使用
DomainPropType
作为参数类型,而是仅使用您实际想要使用的特定类型。
- 在您的构造函数中,正确处理
[number, number]
和 [Date, Date]
情况。
如果您从未打算使用 [Date, Date]
或 [number, number]
调用此对象,选择选项 1 可能是最简单的。
我认为适合您的情况的更具体类型的示例:
type MyDomainPropType = {
x: DomainTuple,
y?: DomainTuple
}
我很抱歉问了一个无聊的问题,但我正在学习打字稿,遇到了我无法克服的情况。
我用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 一次,并且在这种特定情况下,您传递了一个具有 x
和 y
属性的对象,以后您仍然有可能也使用 class 并使用 [number, number]
或 [Date, Date]
格式。
为避免这种情况,您有 2 个选择:
- 不要使用
DomainPropType
作为参数类型,而是仅使用您实际想要使用的特定类型。 - 在您的构造函数中,正确处理
[number, number]
和[Date, Date]
情况。
如果您从未打算使用 [Date, Date]
或 [number, number]
调用此对象,选择选项 1 可能是最简单的。
我认为适合您的情况的更具体类型的示例:
type MyDomainPropType = {
x: DomainTuple,
y?: DomainTuple
}