繁体   English   中英

明确赋值断言和环境声明有什么区别?

[英]What’s the difference between definite assignment assertion and ambient declaration?

当断言一个字段在 class 中肯定被初始化时,有什么区别! (感叹号,明确的赋值断言)和declare修饰符?

以下代码是严格模式下的错误,因为 TS 不确定该字段是否已初始化。

class Person {
    name: string; // Error: Property 'name' has no initializer and is not definitely assigned in the constructor.
}

我见过两种处理方法:

  1. 确定赋值断言:
     class Person { name:; string; }
  2. 环境声明:
     class Person { declare name: string; }

我看不出这两种技术之间的区别。 它们都解决了错误,它们都不发出代码,并且它们都不允许初始化程序。 环境声明(在 v3.7 中发布)是否简单地过时明确的分配(在 v2.7 中发布)? 应该declare使用而不是! 只要有可能?

declare name: string;

这对编译器说:

“有一个名为namestring类型的属性。我不应该向你证明name确实存在,但我还是想使用它。”

declare关键字通常用于类型定义文件,为 Typescript 无法从中获取类型信息的文件(例如纯 JS 文件)提供类型。 因此,如果我正在阅读您的代码,我会假设该name正在从某处的某个 JS 文件中被猴子修补,而您在这里注意到了这一点。

我会不正确。


name!: string;

这对编译器说:

“有一个名为name的属性,其类型为string | undefined 。它以undefined的值开头。但每次获取或设置该属性时,我都想将其视为string类型。”

使用这种形式,任何阅读代码的人都可以清楚地看到, name最初是未定义的,但无论如何都被视为字符串。 这意味着它必须在这个文件的某个地方设置,只是可能不在构造函数中。

从你所说的来看,我在这些假设中是正确的。


在实践中,结果是相同的。 在这两种情况下,您都有一个不需要实际初始化的字符串属性。 但是,我认为name:: string更清楚地说明了实际发生的情况。


最后,我不得不提一下,你可能应该重构你的代码,以便你可以在构造函数中分配属性。 这两种方法都不是类型安全的,因为您可能会将未初始化的值视为string ,如果发生这种情况可能会导致崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM