尽管有严格的空值检查,但未定义的非空文字字符串类型的未初始化字段是未定义的?

时间:2017-04-12 08:55:01

标签: typescript

我认为下面说明的行为是Typescript中的一个错误,并打开了https://github.com/Microsoft/TypeScript/issues/15170。该问题中的代码示例比下面的代码更清楚地说明了问题。

请考虑undefined-literal-string-field.ts中的以下代码:

class Foo {
  public foo: 'foo';
}

const foo = new Foo();

console.log('Foo ', foo.foo);

注意 Foo.fooliteral string type包含undefined。换句话说,请注意该类型仅为'foo',但不是 'foo' | undefined

在Typescript 2.2中,此代码使用--strictNullChecks 编译

$ node_modules/.bin/tsc --version
Version 2.2.2    
$ node_modules/.bin/tsc --strictNullChecks undefined-literal-string-field.ts

但是,该字段在运行时 undefined

$ node undefined-literal-string-field.js
Foo  undefined

显然那是因为它没有在生成的JS代码中初始化:

var Foo = (function () {
    function Foo() {
    }
    return Foo;
}());
var foo = new Foo();
console.log('Foo ', foo.foo);

我可能误解了--strictNullChecks,但据我所知,此标志应禁止undefined作为值,除非该类型是与undefined的联合,即'foo' | undefined。情况并非如此。

为什么Typescript编译器允许我访问类型不允许值undefined 未初始化字段?这不是简单的不健全吗?

并且假设foo的类型只允许单个值 - 为什么编译器不会自动使用允许的一个值来初始化它?

我在这里缺少什么?

2 个答案:

答案 0 :(得分:0)

正如您所写,foo字段未在您的代码中初始化。编译器不会在console.log行中出现任何错误,因为从他的角度来看,类Foo的对象具有这样的字段(无论是初始化还是不是,编译器都不需要担心的是另一个故事) 。

关于第二个问题why the compiler wont initialize the field?答案很简单 - foo: 'foo'定义只是类型定义。初始化正确的值应该在代码中按目的完成。

如果您希望foo具有将要初始化的默认值您可以将班级更改为:

class Foo {
    public foo: 'foo' = 'foo';
}

这应该正确初始化。

答案 1 :(得分:0)

因为你已经把对象搞砸了

const foo =new Foo();

当您使用以下代码时

class Foo {

  public foo : 'foo';

}
let foo: 'foo';

console.log('Foo ', foo.foo);

这将抛出

 error TS2454: Variable 'foo' is used before being assigned.

您缺少应该

的赋值运算符
public foo= 'foo';