在打字稿中,这两种索引签名类型有什么区别?

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

我想根据道具将对象属性设置为布尔值或布尔数组值。

但是当键值作为变量而不是文字字符串值接收时显示错误。

不知道两者的区别

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

第一个索引签名有效,因为您使用的是 any。所以 state.a["test key"] 将是任意的,你可以用 any 做任何事情,包括索引到它。所以这真的有效也就不足为奇了。

你的第二个例子不起作用的原因是打字稿不会缩小对变量的索引访问。所以这有效:

export interface State {
    [key: string]: boolean | boolean[];
}

const state:State = {
}


let test2 = typeof state["test key"] === 'object' && state["test key"][0];

Playground Link

备选方案是使用类型断言,或将 idex 操作的结果放在变量中并缩小范围:

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