使用 Typescript 声明了一个类型,但 Javascript 在内部使用了错误的类型
Declared a type with Typescript but Javascript internally works with a wrong type
我是 Typescript 的新手,正在观看教育视频。昨天我发现了一个奇怪的行为,并认为这是一个错误。
示例:
const json = '{"x": 10, "y":10}';
const coordinates: { x: number; y: number } = JSON.parse(json);
console.log(typeof coordinates.y);
这通常会输出 x 和 y 作为类型编号。但这不是因为类型声明,而是因为 JSON 值。
如果您将其中一个声明为字符串,VS Code 会将其视为字符串,但在内部它仍然是一个数字:
const json = '{"x": 10, "y":10}';
const coordinates: { x: number; y: string } = JSON.parse(json);
console.log(typeof coordinates.y);
这是代码:
如你所见,VS Code 将其视为字符串
但是类型检查证明这是不正确的。
在我看来,解析后的 Object/Array 具有任何类型是有道理的。但如果解析的 JSON-value 与您的注释不同,它应该向您发送错误消息,或者它应该将给定值精确地变形为注释。
我对此很陌生,所以如果我的假设有误,请告诉我!
Typescript 在编译 之前和期间进行推理。编译成 JS 后,如果你的某些代码的类型逻辑不健全,你声明的某些类型可能是无效的。这就是这里发生的事情。
JSON.parse
returns any
类型的东西,可以是字面上的任何东西。您可以尝试使用以下行从中提取属性:
const coordinates: { x: number; y: string } = JSON.parse(json);
但这并不意味着解析后的对象实际上会有 x
属性 作为数字,或 y
属性 作为字符串 - 您的代码告诉编译器 假设 它确实如此,并在代码后面将 y
视为字符串。
如果你有一些东西,默认,类型any
,当从它提取属性时,你应该确保它的属性确实是您指定的类型。如果您不能 100% 确定属性将始终符合预期(例如,如果输入字符串来自网络响应 - 如果响应是 503
怎么办?),请进行类型保护,例如:
const isCoordinates = (param: unknown): param is { x: number, y: number } => {
return typeof param === 'object' && param !== null && 'x' in param;
};
然后在尝试从字符串中提取属性之前调用 isCoordinates
以确保它是您首先期望的格式。
否则,就像这里发生的那样,你可以告诉编译器一些东西 false,结果可能会出现错误和奇怪的事情。
您可以考虑启用 tslint 规则 no-unsafe-any 以避免犯此类错误。
我是 Typescript 的新手,正在观看教育视频。昨天我发现了一个奇怪的行为,并认为这是一个错误。 示例:
const json = '{"x": 10, "y":10}';
const coordinates: { x: number; y: number } = JSON.parse(json);
console.log(typeof coordinates.y);
这通常会输出 x 和 y 作为类型编号。但这不是因为类型声明,而是因为 JSON 值。 如果您将其中一个声明为字符串,VS Code 会将其视为字符串,但在内部它仍然是一个数字:
const json = '{"x": 10, "y":10}';
const coordinates: { x: number; y: string } = JSON.parse(json);
console.log(typeof coordinates.y);
这是代码:
如你所见,VS Code 将其视为字符串
但是类型检查证明这是不正确的。
在我看来,解析后的 Object/Array 具有任何类型是有道理的。但如果解析的 JSON-value 与您的注释不同,它应该向您发送错误消息,或者它应该将给定值精确地变形为注释。
我对此很陌生,所以如果我的假设有误,请告诉我!
Typescript 在编译 之前和期间进行推理。编译成 JS 后,如果你的某些代码的类型逻辑不健全,你声明的某些类型可能是无效的。这就是这里发生的事情。
JSON.parse
returns any
类型的东西,可以是字面上的任何东西。您可以尝试使用以下行从中提取属性:
const coordinates: { x: number; y: string } = JSON.parse(json);
但这并不意味着解析后的对象实际上会有 x
属性 作为数字,或 y
属性 作为字符串 - 您的代码告诉编译器 假设 它确实如此,并在代码后面将 y
视为字符串。
如果你有一些东西,默认,类型any
,当从它提取属性时,你应该确保它的属性确实是您指定的类型。如果您不能 100% 确定属性将始终符合预期(例如,如果输入字符串来自网络响应 - 如果响应是 503
怎么办?),请进行类型保护,例如:
const isCoordinates = (param: unknown): param is { x: number, y: number } => {
return typeof param === 'object' && param !== null && 'x' in param;
};
然后在尝试从字符串中提取属性之前调用 isCoordinates
以确保它是您首先期望的格式。
否则,就像这里发生的那样,你可以告诉编译器一些东西 false,结果可能会出现错误和奇怪的事情。
您可以考虑启用 tslint 规则 no-unsafe-any 以避免犯此类错误。