好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

typescript中的 null 和 undefined

null 和 undefined 是 ts 中的基础类型,分别具有值 null 和 undefined,默认情况下它们是所有类型的子类型,即可以赋值给任意类型,如:

let s: string = 'hello' 

s  =  null   //  right 
s = undefined  //   right 

但当我们在 tsconfig.js 文件中设置 strictNullChecks 为 true 时,就不能将 null 和 undefined 赋值给除它们自身和 void 之外的任意类型了。在这种严格检查的情况下,如果你确实在某个地方想要给一个其他类型的值设置初始值为空,然后再赋值,可以使用联合类型来实现:

 //   开启 "strictNullChecks": true 情况 
 
let s: string  = 'hello' 
s  =  null   //   error,不能将类型“null”分配给类型“string”。 
 
let s2: string  |  null  = 'hi' 
s2  =  null  
s2  = undefined  //   error,不能将类型“undefined”分配给类型“string | null”。 

从例子中知道,null 和 undefined 是区别的,即 string|undefined、string|null 和 string|undefined|null 是三种不同的类型。

 

可选参数和可选属性

如果设置了 "strictNullChecks": true,可选参数会被自动加上 |undefined,例子:

 function  f(x: number, y? : number){
      return  x + (y || 0 )
}
f( 1, 2)  //   3 
f(1)  //   1 
f(1, undefined)  //   1 
f(1,  null )  //   error,类型“null”的参数不能赋给类型“number | undefined”的参数。 

对于可选属性也会有同样的处理:

 interface PositionInterface{
    x: number
    y ? : number
}

let p: PositionInterface  = {x: 10 }
p.y  = 'abc'  //   error,不能将类型“"abc"”分配给类型“number | undefined”。 
 
p.y  =  null   //   error,不能将类型“null”分配给类型“number | undefined”。 
 
p.y  = undefined  //   right 

 

类型保护和类型断言

可以为 null 的类型是通过联合类型实现,所以需要使用类型保护去除 null,如:

 function  f(sn: string |  null  ): string{
      if (sn ===  null  ){
          return  'null' 
    }   else   {
          return   sn
    }
} 

这样操作可以去除 null,或者使用短路运算符:

 function  f(sn: string |  null  ): string{
     return  sn || 'null' 
} 

 

如果编译器无法去除 null 和 undefined,可以使用类型断言手动去除。语法是添加 ! 后缀:  identifier!  从  identifier  的类型里去除了  null 和  undefined,官方例子:

 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 的类型。

 

查看更多关于typescript中的 null 和 undefined的详细内容...

  阅读:59次