Home > Mobile >  in typescript, What's the difference between these two index signature type?
in typescript, What's the difference between these two index signature type?

Time:03-29

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];

Playground Link

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];

Playground Link

  • Related