typescript - 为什么我需要在我的声明中使用类型断言将变量分配给 null?

标签 typescript

我很困惑为什么下面的变量 a 的类型不是 LoadStatus,即使我明确地将它放在声明中:

type LoadStatus = 'succeess'|'failure'|null;

let a: LoadStatus = null;
let b = null as LoadStatus;
a; // type is null
b; // type is LoadStatus

我使用 Typescript playground 检查了类型。

最佳答案

这是设计使然。如果不是这样,那么杂项类型的机制就没有那么有用了。对于 example :

type LoadStatus = 'success' | 'failure' | null;

let a: LoadStatus = null;
let b = null as LoadStatus;
a ; // type is null

b; // type is LoadStatus

// null is converted to 'failure', so that always a string is returned
type ConvertLoadStatus<T extends LoadStatus> = T extends null ? 'failure' : T;

type resultA = ConvertLoadStatus<typeof a>; // failure;
type resultB = ConvertLoadStatus<typeof b>; // 'success' | 'failure', not very helpful

a = 5; // a is still not assignable to other things than described, so typing still protects the variable

另一个示例是检查 null or undefined 时的 if 语句:

type ExampleType = {a: string, b: number} | null;

function doSomething(a: ExampleType) {
  if(a != null) {
    a // a is {a: string, b: number}
    a.a // a can now be accessed
    // How would we ever be able to access a if it always stayed ExampleType?
  }
  a.a // Object is possibly 'null'
}

编辑:正如@Boug 指出的那样,所有内容都在 narrowing 下进行了描述.

关于typescript - 为什么我需要在我的声明中使用类型断言将变量分配给 null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66713781/

相关文章:

javascript - Angular 2 中的 Leaflet + Google - 瓷砖顺序错误

typescript - 如何在 immer 上更新草稿时动态添加新属性?

typescript - 不要扩大对象字面量中潜在的字面量类型

android - Ionic 2 Native Audio 在浏览器中抛出错误

unit-testing - Angular 2 TestBed,没有依赖注入(inject)的模拟方法

typescript - 解决VS 2017中的 'Conflicting definitions for node' TS4090错误

visual-studio - 如何停止 visual studio 关于存在 'public' 修饰符的警告

typescript - 在 TypeScript 中生成 "Unreachable code detected"编译警告而不是错误?

node.js - 无法加载资源:net::ERR_CONNECTION_REFUSED:Nodejs

Angular 2 : Cannot set property 'location' of null