I am getting various different data structures from external sources. In get() i am checking for undefined and existence of the property, but still getting compiler errors.
Is there a quick fix for that as we are just prototyping at the moment ?
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 '';
}
}
Error:
Property 'session' does not exist on type 'object'.
AFAIK, type object is too general. I think it is better to use Record<string, unknown>.
Please see ts eslint rule:
Unsafe:
//bad
const lowerObj: object = {};
Safe:
// good
const lowerObj: Record<string, unknown> = {};
Using hasOwnProperty is ok, but using Object.prototype.hasOwnProperty.call(foo, "bar") is much better. See eslint rule.
Here you can find recent optimization of V8 engine regarding using hasOwnProperty.
You can find more typings for hasOwnProperty in my article
Hence, this code should be ok:
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 '';
}
}
Playground
Object instead of object link'key' in obj instead of hasOwnProperty linkclass 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 '';
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With