我从外部来源获得各种不同的数据结构。在get()
中,我检查undefined
和existence
的属性,但仍然得到编译器错误。
是否有一个快速的解决方案,因为我们现在只是原型设计?
class MyCache {
private map: Map<string, object>;
constructor() {
this.map = new Map<string, object>();
}
populateMap(uuid: string): boolean {
// ... getting a JSON object from somewhere
let externalData: object = {};
if (uuid == 'abc...') {
externalData = {"bar": "BAR", "session": uuid}
} else if( uuid == "def...") {
externalData = {"foo": "FOO", "session": uuid}
// ... some more else ifs ...
} else {
externalData = {"baz": "BAZ", "session": uuid}
}
this.map.set(uuid, externalData);
console.log(externalData);
return true;
}
get(uuid: string) {
let response = this.map.get(uuid) || {'session': null};
if (response.hasOwnProperty('session')) {
return response.session;
}
return '';
}
}
错误:
Property 'session' does not exist on type 'object'.
哎呀,object
类型太笼统了。我觉得用Record<string, unknown>
比较好。请参阅eslint规则:
不安全:
//bad
const lowerObj: object = {};
安全:
// good
const lowerObj: Record<string, unknown> = {};
使用hasOwnProperty
是可以的,但使用Object.prototype.hasOwnProperty.call(foo, "bar")
要好得多。参见eslint rule.
在这里你可以找到关于使用hasOwnProperty
的V8引擎的最新优化。
您可以在我的文章
中找到hasOwnProperty
的更多类型因此,这段代码应该没问题:
class MyCache {
private map: Map<string, Record<string, unknown>>;
constructor() {
this.map = new Map<string, Record<string, unknown>>();
}
populateMap(uuid: string): boolean {
// ... getting a JSON Record<string, unknown> from somewhere
let externalData: Record<string, unknown> = {};
if (uuid == 'abc...') {
externalData = { "bar": "BAR", "session": uuid }
} else if (uuid == "def...") {
externalData = { "foo": "FOO", "session": uuid }
// ... some more else ifs ...
} else {
externalData = { "baz": "BAZ", "session": uuid }
}
this.map.set(uuid, externalData);
console.log(externalData);
return true;
}
get(uuid: string) {
let response = this.map.get(uuid) || { 'session': null };
if (response.hasOwnProperty('session')) {
return response.session;
}
return '';
}
}
游乐场
- 使用
Object
代替object
link - 使用
'key' in obj
代替hasOwnProperty
link
class MyCache {
private map: Map<string, Object>;
constructor() {
this.map = new Map(); // No need for generic parameters, type is already set in the property declaration
}
get(uuid: string) {
let response = this.map.get(uuid) || { 'session': null };
if ('session' in response) {
return response.session;
}
return '';
}
}