虽然您可以更改类型注释person
,也许像:
let person: { name: string; salary?: number } = {
name: 'Harry'
};
or even:
let person = {
name: 'Harry'
} as { name: string; salary: number };
最安全的方法可能是(ab)使用断言函数 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions在 3.7 版本中:
function defineProperty<
O,
Property extends PropertyKey,
Value
>(o: O, key: Property, attributes: PropertyDescriptor & ThisType<any> & { value: Value }): asserts o is O & Record<Property, Value> {
Object.defineProperty(o, key, attributes);
}
它本质上是一个包装函数Object.defineProperty
告诉 TypeScript,如果这个函数没有抛出错误,那么给定值的类型o
is O & Record<Property, Value>
.
所以当你使用它时,你会得到这样的类型:
defineProperty(person,'salary',{enumerable: false, value : 15});
person
// ^? { name: string; } & Record<"salary", number>
操场 https://tsplay.dev/mx3vbN
如果你really如果愿意,您还可以通过将断言更改为以下内容来使结果类型更清晰:
asserts o is (O & Record<Property, Value> extends infer T extends O ? { [K in keyof T]: T[K] } : O)
如你看到的here https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABAEwKbBmVAFATnAB1VygE8AeAWAChE7EB5AGhvsT0OLMVQA8pUYZAGd2+IiVIBpVKRa16ANQCGAGxCoaAPgAUcAFyMmiANazDHCWWPKoUXDABGIAcIviupACKphEBwRQcLiIAGSIACoAFjDCEaRE5MpgpFphiADeiABuahqGKuqoiAC+AJSGysLCXKJwiLGIOgzpAEqoEMHI5JaexoUaaXwCQqKYwMSRPPyCIoyIAPyZiADaUg1IZqRwwJEAuoYRa3uliIYMZZms9AyOAFYdUAB0aBhYvZJ6xls2dg7OrjKAG4aCUaDRVKgoIgJMIEIgALxXBRgZQAW1QhgA5AAJZS4XCkLGgkHUGi3B7QF7oTA4DyfWEIJhY4RqfFEpgZQQgDG4ZSOSGGYBqGrGXJFM6IACMAFZyqSaJ0wHDIU9VHAAOY6RlgJ6s1Ts4Hg6ivWkfMja4hwsDM-XsrGc7m8-mCxDC1SinJ5YqGWXy41KlWoNWay24a16tmEso0IA当悬停在person
,现在的类型是{ name: string; salary: number; }
而不是一个丑陋的十字路口。