Reputation: 1407
I really need to be able to check dynamically if aa is a property of my complex object called validations
const check = 'propertya' + 'a'; // result of a complex calculation that returns string 'propertyaa'
validations= {
'a' : {
'propertyaa': 'ax',
'ab': 'ay',
'ac': 'az'
},
'b' : {
'ba': 'ax',
'bb': 'ay',
'bc': 'az'
}
};
if (this.validations.a[check] === undefined) { ...
Error is:
element implicitly has an any type because type '{ ' propertyaa': string, 'ab': string, 'ac': string; }' has no index signature
(property) 'a': {
'propertyaa': string;
'ab': string;
'ac': string;
}
Curiously the static (not dynamic) variant works if (this.validations.a['ab']) {
Upvotes: 2
Views: 1747
Reputation: 1407
There is a simpler solution and really the only one that works for me so far:
cartoons = {
'producers': {
'Disney': 'Walt Disney',
'PIXAR1': 'John John'
}
}
const check = 'Dis' + 'ney';
const y = (<any>this.cartoons.producers)[check]; // notice the cast to any
alert(y);
Upvotes: 0
Reputation: 250156
You can go one of two routes. You can either add an index signature to your validation properties:
type Indexable = { [name: string]: string }
const validations = {
'a': {
'propertyaa': 'ax',
'ab': 'ay',
'ac': 'az'
} as Indexable,
'b': {
'ba': 'ax',
'bb': 'ay',
'bc': 'az'
} as Indexable
};
const check = 'propertya' + 'a';
if (validations.a[check] === undefined) {
}
You could also just cast the property to Indexable
when you use it:
if ((validations.a as Indexable)[check] === undefined) {
}
You could also use any
instead of Indexable
, but the Indexable
defined above provides more type safety then any
Another option is to assert that the string check
is in fact a key for the value of a
:
if (validations.a[check as 'propertyaa'] === undefined) {
}
Edit
If you go with the first option, a helper function can help avoid the need for the type assertion on each property of validations
:
type Indexable = { [name: string]: string }
const validations = createValidations({
'a': {
'propertyaa': 'ax',
'ab': '19',
'ac': 'az'
},
'b': {
'ba': 'ax',
'bb': 'ay',
'bc': 'az'
}
});
function createValidations<T>(o: { [P in keyof T]: T[P] & Indexable}) : typeof o {
return o;
}
const check = 'propertya' + 'a';
if (validations.a[check] === undefined) {
}
Upvotes: 1
Reputation: 17895
You will need index signature...
interface ComplexObject {
[index: string ]: string | ComplexObject;
}
const check = 'propertya' + 'a';
const validations: ComplexObject = {
'a' : {
'propertyaa': 'ax',
'ab': 'ay',
'ac': 'az'
},
'b' : {
'ba': 'ax',
'bb': 'ay',
'bc': 'az'
}
};
if (this.validations.a[check] === undefined) {
// ...
}
Upvotes: 0