You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何修复null类型不能用作索引类型报错

问题场景

使用TypeScript开发时,声明了预期返回字符串类型值的lang变量,以及包含两个属性的direction对象,需要编写函数根据lang取值返回direction对应的属性值,编写direction[lang]时触发报错:Type 'null' cannot be used as an index type.,已确认lang永远不会为null,需要修复该问题。

原有问题代码:

export const lang = localStorage.getItem('lang') ? localStorage.getItem('lang') : "en";

export const direction  = {
    ru: "rtl",
    en: "ltr"
}

function getDirection() {
    return direction[lang];
}
报错原因

localStorage.getItem()的TypeScript内置返回类型为string | null,原有代码中三元表达式的判断分支和取值分支两次独立调用localStorage.getItem('lang'),TypeScript不会默认两次调用的返回结果完全一致,因此最终推断lang的类型仍为string | null,而null类型不能作为对象的索引值,因此触发类型报错。

修复方案
  • 方案1(推荐):单次读取localStorage值存入临时变量,让TypeScript正确识别类型判断逻辑,同时避免重复调用localStorage的冗余开销
// 仅调用一次getItem,TS可自动识别三元判断已经排除null类型
const storedLang = localStorage.getItem('lang');
export const lang = storedLang ? storedLang : "en";

export const direction  = {
    ru: "rtl",
    en: "ltr"
}

function getDirection() {
    return direction[lang];
}

修复后TS会自动推断lang类型为string,可直接作为对象索引使用,不会触发报错。

  • 方案2:使用非空断言操作符!,明确告知TypeScript该位置的值不可能为null,适合100%确认值非空的场景
// 在真值分支的getItem返回值后加!,标记该值非null
export const lang = localStorage.getItem('lang') ? localStorage.getItem('lang')! : "en";

export const direction  = {
    ru: "rtl",
    en: "ltr"
}

function getDirection() {
    return direction[lang];
}

注意:非空断言属于类型绕过手段,不会做实际的运行时校验,如果后续逻辑变动导致该位置值为null,TS不会提前抛出提示,生产环境可能出现异常,优先使用方案1的自动类型推断更稳妥。

  • 方案3(类型最严谨):显式约束lang的类型为direction的合法键值,从根源避免传入不存在的属性键导致的取值错误
const storedLang = localStorage.getItem('lang');
// 显式声明lang的类型只能是direction已有的键,兜底值"en"符合类型约束
export const lang: keyof typeof direction = storedLang ? storedLang as keyof typeof direction : "en";

export const direction  = {
    ru: "rtl",
    en: "ltr"
}

function getDirection() {
    return direction[lang];
}

内容的提问来源于stack exchange,提问作者SteveRicky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:24:14