typescript - Typescript - 文字类型推断 - 与字符串和数字不同的行为
问题描述
根据TypeScript Literal Types,我们可以在类型位置引用特定的字符串和数字。所以以下是有效的。
function printText(s: string, alignment: "left" | "right") {
// ...
}
printText("Hello, world", "left"); // This works
printText("G'day, mate", "centre"); // This gives error - Argument of type '"centre"' is not assignable to parameter of type '"left" | "right"'.
但是,这不适用于使用对象初始化变量时,因为 TypeScript 假定该对象的属性稍后可能会更改值。解决方法是添加类型断言(在任一位置 - 更改 1 和更改 2)。
例如
// Change 1:
const req = { url: "https://example.com", method: "GET" as "GET" };
// Change 2
handleRequest(req.url, req.method as "GET");
以上将起作用。但是如果我尝试在方法属性中插入一些不同的字符串,这些也会被认为是有效的。虽然如果我添加一个数字就不会。例如
function handleRequest(url: string, method: "GET"|"POST"):void{
console.log(method);
}
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method as "POST"); // This is accepted and works
const req1 = { url: "https://example.com", method: "ABCD" };
handleRequest(req1.url, req1.method as "GET"); // This is accepted and works
const req2 = { url: "https://example.com", method: 2 };
handleRequest(req2.url, req2.method as "GET"); // This throws an error - Conversion of type 'number' to type '"GET"' may be a mistake because neither type sufficiently overlaps with the other.
TypeScript 在与数字比较时能够正确编译,但在涉及其他字符串时不能正确编译?
解决方案
类型断言是一种告诉 typescript 不要检查你的工作的方法。如果使用不当,可能会引入错误。由于这种导致错误的可能性,即使您进行类型断言,typescript 也会进行一些最少的检查,如果它发现您断言的类型与计算的类型大不相同,它会给您一个类型错误。
因此,当您尝试断言通用字符串是特定字符串时,打字稿会认为“是的,这已经足够接近了,我会按照他们的要求去做”。但是当你试图断言一个数字是一个字符串时,打字稿会说“哇,这没有意义。你确定吗?”。如果你真的确定,那么你可以通过这样做来永久关闭打字稿,在你的情况下,req2.method as unknown as "GET"
PS:更安全的选择是使用as const
. 这告诉打字稿假设值不会改变,否则要准确使用它在代码中看到的内容。例如:
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method); // This is accepted and works
const req1 = { url: "https://example.com", method: "ABCD" } as const;
handleRequest(req1.url, req1.method); // This correctly throws an error
const req2 = { url: "https://example.com", method: 2 } as const;
handleRequest(req2.url, req2.method); // This correctly throws an error
或者,给它一个显式类型并完全跳过对断言的需求。
const req1: { url: string, method: 'GET' | 'POST' } = {
url: "https://example.com",
method: "ABCD", // Error here
}
推荐阅读
- react-native - 通过调用 onPress 函数导航到新屏幕
- apache-zookeeper - Zookeeper - 当前时代出错,比上一个 zxid 更旧
- python - 使用 Pyshark 对 JSON 数据包中的键和值进行配对
- javascript - AsyncData 与 nuxtServerInit
- java - 带有 Webview 的应用程序。如何在我的网站上创建链接以在桌面上创建快捷方式以在 Webview 中打开该页面?
- javascript - 如何将数据组合在一个数组中并组合链接列(收入)的值?
- c# - 是否可以在日志文件中插入自定义行作为第一行?
- angular - 在子模块中使用 app.module 中提供的类
- c# - 在更新“多个”时将所选项目分配给下拉列表
- c# - 从大量字符中减去 ASCII 值的最快方法是什么