Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

>Solution :

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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading