即使在Typescript中添加了类型Assert,我们还需要类型注解吗?

jyztefdp  于 2023-06-07  发布在  TypeScript
关注(0)|答案(1)|浏览(130)

如果我们在Typescript中指定as,我们真的需要指定变量的类型吗?
例如:下面的代码给了我相同类型的对象。但我想知道正确的方法。

const x: Student = {
  name: "John"
}

// is the above same as below

const x = {
  name: "John"
} as Student;

// or do we need to specify both

const x: Student = {
  name: "John"
} as Student;

export interface Student {
  name: string,
  id?: string
}
yhuiod9q

yhuiod9q1#

类型注解和类型Assert服务于不同但部分重叠的需求;很少有人会同时使用这两种功能。

  • type annotation* 允许您显式地选择变量的类型。它往往是不必要的;如果没有显式的类型注解,变量的类型通常可以是inferred,这取决于它的初始化值的类型。如果该值的类型满足您的需要,那么注解本质上是多余的。如果该值的类型不够充分,则注解会有所帮助。例如在
const x = { name: "John" }
/* const x: { name: string; } */

编译器将x的类型推断为{name: string}。这可以分配给Student,因此根据您的用例,它可能足够了:

function acceptStudent(s: Student) { }
acceptStudent(x); // works

但如果您愿意,可以随意使用注解:

const x: Student = {
  name: "John"
}

类型注解的检查相当严格。如果你用与初始化器不兼容的类型注解一个变量,你会得到一个错误:

const x: Student = { // error!
  id: "John",
}

另一方面,type assertion 让你声明一个表达式是某种类型的。这主要用于当您对表达式类型的了解超过编译器可以验证的范围时。你 * Assert * 它,尽管编译器无法看到Assert是真的。实际上,另一个用例是当你需要故意向编译器隐瞒一个表达式的类型以便继续时。同样,它也经常是不必要的,因为编译器为这样的表达式推断的类型通常是合理的。但是有时候你想改变编译器对表达式类型的看法:

const x = {
  id: "John"
} as Student; // no error

这里编译器不会抱怨,即使{id: "John"}不是有效的Student。不过,它已经足够接近,编译器可以接受您的Assert。
这取决于你的需求是什么。这里的一般建议大致是:更喜欢注解而不是Assert,更喜欢推理而不是注解。如果推理足够,那么就使用它。如果没有,则进行注解。如果这仍然不起作用,那么考虑Assert(但要小心)。而使用 * 两者 * 几乎肯定是矫枉过正。一旦Assert了初始化表达式的类型,该类型将是变量的推断类型,因此注解是多余的。
Playground链接到代码

相关问题