我有一个异步加载数据的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
,但是如果不使用任何方法,就无法让访问者工作。
type PossiblyUninitialized<T> = T | { [key in keyof T]: undefined };
类型“{}”不能指定为“PossiblyUninitialized”类型。
类型'{}'不能分配给'{id:undefined;名称:未定义; }”。
“{}”类型中缺少属性“id”。
尝试将空对象分配给属性时抛出错误。这与this keyof question。
有关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'])
,但这不是我想要做的。
答案 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] };