了解类型鉴定



我刚开始使用typescript,尽管我认为事情会很容易,但typescript似乎与javascript不太相似,而且有点混淆

无论如何,在打字脚本中(不确定我的代码是否有效(,做这样的有什么区别

const ua: string = req.headers['user-agent']!

或者按照这样的回答:https://stackoverflow.com/a/38831495/10433835

const us = <string> req.headers['user-agent']!

Ps:我不确定哪个代码是有效的。

const ua: string = req.headers['user-agent']!

意味着您创建了一个名为ua的新变量,该变量被明确设置为字符串类型并为其赋值。如果您试图将非字符串的内容分配给同一变量,例如const ua: string = 42,这将触发错误

const us = <string> req.headers['user-agent']!

在这种情况下,您只是创建了一个名为us的新变量,该变量没有定义显式类型。在这种情况中,TypeScript将尝试根据您分配的内容进行猜测。例如,请参阅此

let a = "hello"; //no type for `a` but assigning a string makes the guess to be `string`
a = 42; //error because it's not a string

TypeScript游乐场

当您使用<string>进行显式类型断言时,您保证TS会猜测类型为string


在这两者中,第一个更安全,因为你知道你需要一个字符串,如果不是,那么你会得到一个编译时错误。第二种方法依赖于隐式类型猜测,这实际上可能是错误的。这意味着在编译时,这将是正确的,因为您否决了编译器,但不一定在运行时工作。这里有一个例子:

let a = <string> getData();
function getData(): string | number {
return 42;
}

TypeScript游乐场

这将进行编译,但这是不正确的,因为你已经告诉编译器总是期望一个字符串,它实际上可能是一个数字(返回类型是string | number,所以它可以是任意一个(,而且,函数无论如何都只返回一个数字。因此,在运行时,在此之后就没有类型保证了。与显式键入比较

let a: string = getData();
function getData(): string | number {
return 42;
}

TypeScript游乐场

现在,您可以正确地获得编译时错误,因为您应该处理获得不同类型时发生的情况。

因此,通常应避免手动类型断言。它可能会导致错误,这些错误最初可能不存在,但后来可能会出现——例如,上面的代码最初可能让getData只返回string,因此在这一点上,变量a的显式和隐式类型没有区别。通过<string>的类型断言是多余的。但是,如果函数随后更改为返回string | number,则显式类型断言将变得不可靠。

我的意思是区别在于,在第一个例子中,您声明类型字符串的常量为其分配req标头的"用户代理"值

在第二个例子中,您将声明常量类型any,并将其显式分配给req标头的"用户代理"的类型字符串值

我不确定我是否回答了你的问题,如果没有,请提供更多的上下文。两个代码示例都是"有效"的。

这两个表达式都有效。但它们意味着不同的意图。

案例1:

const ua: string = req.headers['user-agent']!
  1. 您声明了一个变量ua并将其标记为string类型
  2. 你给它赋值
  3. typescript将检查该值是否适合分配给该变量

情况2:

const ua = <string>req.headers['user-agent']!
  1. 声明变量ua而不指定其类型
  2. 为其分配一个值,手动键入断言为string类型
  3. typescript将检查:
    • 如果您的类型断言适用于该值
    • 如果以上是好的,那么它将从该赋值推断ua的类型

最新更新