访问unitiliazied TypeScript字段

时间:2017-12-18 17:40:44

标签: typescript

我有一个异步加载数据的JavaScript类,但我想从中提取一个属性

interface Header {
    id: number;
    name: string;
}

class RecordWithHeader {
    header: PossiblyUninitialized<Header> = {};

    constructor(private dataService) { }

    loadData() {
        this.dataService.getHeader()
            .then((header: Header) => this.header = header);
    }

    print() {
        // want to print possibly undefined value without checking if initialized
        console.log('The id is', this.header.id);
    }
}

我已经尝试了几种方法来定义PossiblyUninitialized,但是如果不使用任何方法,就无法让访问者工作。

尝试1:地图键

type PossiblyUninitialized<T> = T | { [key in keyof T]: undefined };
  

类型“{}”不能指定为“PossiblyUninitialized”类型。

     

类型'{}'不能分配给'{id:undefined;名称:未定义; }”。

     

“{}”类型中缺少属性“id”。

尝试将空对象分配给属性时抛出错误。这与this keyof question

有关

尝试2:基本地图

type PossiblyUninitialized<T> = T | { [key: string]: undefined };
  

'PossiblyUninitialized'类型中不存在属性'id'。

     

属性'id'在类型'{[key:string]上不存在:undefined; }”。

type PossiblyUninitialized<T> = T | { [key: string]: any };
  

'PossiblyUninitialized'类型中不存在属性'id'。

     

属性'id'在类型'{[key:string]上不存在:any; }”。

这是尝试使用没有keyof限制的更简单的地图。但TypeScript不喜欢属性访问器。 注意:这适用于console.log('ID', this.header['id']),但这不是我想要做的。

2 个答案:

答案 0 :(得分:0)

因此,似乎不可能让TypeScript仅使用类型注释处理此用例。但是,您可以使用类型转换来强制TypeScript理解空对象。

使用类型

type PossiblyUninitialized<T> = T | { [key in keyof T]: undefined };

或使用TypeScript的Record类型

定义
type PossiblyUninitialized<T> = T | Record<keyof T, undefined>;

然后可以通过强制转换为该类型来定义header属性。

header = <PossiblyUninitialized<Header>> {};

或以TSX兼容的方式

header = {} as PossiblyUninitialized<Header>;

这会保留标题属性的语法高亮显示。此外,如果您启用了严格的空值检查,TypeScript将识别id类型的number | undefined属性和name属性string | undefined。要查看此信息,view it in the TypeScript Playground

答案 1 :(得分:0)

我猜您需要的是以下内容:

type PossiblyUninitialized<T> = { [key in keyof T]?: T[key] };