I want to set the object attribute to be either a boolean value or an boolean array value depending on the props.
But it shows an error when the key value is received as a variable rather than a literal string value.
I don't know the difference between two.
export interface State {
a: {
[key: string]: any[];
};
b: {
[key: string]: boolean | boolean[];
};
}
const state:State = {
a: {},
b: {},
}
const key:string = "test key";
// this works
let test1 = typeof state.b["test key"] === 'object' && state.a["test key"][0];
// type error : Property '0' does not exist on type 'boolean | boolean[]
let test2 = typeof state.b[key] === 'object' && state.b[key][0];
CodePudding user response:
The first index signature works because you are using any
. So state.a["test key"]
will be any, and you can do anything with any
, including indexing into it. So it's not really surprising this actually works.
The reason your second example doesn't work, is because typescript will not narrow index access with a variable. So this works:
export interface State {
[key: string]: boolean | boolean[];
}
const state:State = {
}
let test2 = typeof state["test key"] === 'object' && state["test key"][0];
The alternatives are to use a type assertion, or put the result of the idex operation in a variable and narrow that:
const key:string = "test key";
// This does not work
let test2 = typeof state[key] === 'object' && state[key][0];
// This works
let keyValue = state[key];
let test3 = typeof keyValue === 'object' && keyValue[0];
// Or with a assertion
let test4 = typeof state[key] === 'object' && (state[key] as boolean[])[0];