TypeScript基础入门之高级类型的可null类型

转发ide

TypeScript基础入门之高级类型的可null类型

高级类型

可null类型(Nullable Types)

TypeScript具备两种特殊的类型,null和undefined,它们分别具备值null和undefined。 默认状况下,类型检查器认为null与undefined能够赋值给任何类型。
null与undefined是全部其它类型的一个有效值。 这也意味着,你阻止不了将它们赋值给其它类型,就算是你想要阻止这种状况也不行。
null的发明者,Tony Hoare,称它为价值亿万美金的错误。函数

--strictNullChecks标记能够解决此错误:当你声明一个变量时,它不会自动地包含null或undefined。
你可使用联合类型明确的包含它们,以下post

let s = "foo";
s = null; // 错误, 'null'不能赋值给'string'
let sn: string | null = "bar";
sn = null; // 能够

sn = undefined; // error, 'undefined'不能赋值给'string | null'

注意,按照JavaScript的语义,TypeScript会把null和undefined区别对待。 
string | null,string | undefined和 string | undefined | null是不一样的类型。spa

可选参数和可选属性

使用了 --strictNullChecks,可选参数会被自动地加上| undefined:code

function f(x: number, y?: number) {
    return x + (y || 0);
}
f(1, 2);
f(1);
f(1, undefined);
f(1, null); // error, 'null' is not assignable to 'number | undefined'

可选属性也会有一样的处理:blog

class C {
    a: number;
    b?: number;
}
let c = new C();
c.a = 12;
c.a = undefined; // error, 'undefined' is not assignable to 'number'
c.b = 13;
c.b = undefined; // ok
c.b = null; // error, 'null' is not assignable to 'number | undefined'

类型保护和类型断言

因为能够为null的类型是经过联合类型实现,那么你须要使用类型保护来去除 null。 幸运地是这与在JavaScript里写的代码一致:ip

function f(sn: string | null): string {
    if (sn == null) {
        return "default";
    } else {
        return sn;
    }
}

这里很明显地去除了null,你也可使用||运算符:get

function f(sn: string | null): string {
    return sn || "default";
}

若是编译器不可以去除null或undefined,你可使用类型断言手动去除。 语法是添加!后缀:identifier!从identifier的类型里去除了null和undefined:编译器

先看第一个失败的例子string

function broken(name: string | null): string {
  function postfix(epithet: string) {
    return name.charAt(0) + '.  the ' + epithet; // error, 'name' is possibly null
  }
  name = name || "Bob";
  return postfix("great");
}


在看下第二个成功的例子

function fixed(name: string | null): string {
  function postfix(epithet: string) {
    return name!.charAt(0) + '.  the ' + epithet; // ok
  }
  name = name || "Bob";
  return postfix("great");
}

上面的例子使用了嵌套函数,由于编译器没法去除嵌套函数的null(除非是当即调用的函数表达式)。 由于它没法跟踪全部对嵌套函数的调用,尤为是你将内层函数作为外层函数的返回值。 若是没法知道函数在哪里被调用,就没法知道调用时name的类型。

相关文章
相关标签/搜索