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

TypeScript报错:Type 'TypeName'无法用作索引类型,求解决方案

TypeScript索引类型报错排查与解决

问题背景

开发Pokemon相关TypeScript应用时,遇到Type 'TypeName' cannot be used as an index type报错,尝试将String改为string等方法无效;后续修改后原错误消失,但样式组件中再次出现相同问题。

报错场景1:数据请求逻辑

相关代码:

useEffect(() => {
    async function getPokemonDetails(){
        try {
            const response = await api.get(`/pokemon/${pokemonId}`)
            const {id, name, stats, abilities, types} = response.data

            const currentType = types[0].type.name as TypeName;
            const color = colors.type[currentType]

            setPokemon({
                id, name, stats, abilities, color, types
            })
        } catch (error) {
            
        }
    }

    getPokemonDetails()
})

报错行:const color = colors.type[currentType],提示Type 'TypeName' cannot be used as an index type。

相关类型与配置定义

TypeName类型

type TypeName = {
    name: |
    'bug' |
    'dark' |
    'dragon' |
    'electric' |
    'fairy' |
    'fighting' |
    'fire' |
    'flying' |
    'ghost' |
    'grass' |
    'ground' |
    'ice' |
    'normal' |
    'poison' |
    'psychic' |
    'rock' |
    'steel' |
    'water'
}

colors配置

export default {
    colors: {
        type: {
            bug: '#8CB230',
            dark: '#58575F',
            dragon: '#0F6AC0',
            electric: '#EED535',
            fairy: '#ED6EC7',
            fighting: '#D04164',
            fire: '#FD7D24',
            flying: '#748FC9',
            ghost: '#556AAE',
            grass: '#62B957',
            ground: '#DD7748',
            ice: '#61CEC0',
            normal: '#9DA0AA',
            poison: '#A552CC',
            psychic: '#EA5D60',
            rock: '#BAAB82',
            steel: '#417D9A',
            water: '#4A90DA',
        },
    }
}

报错场景2:样式组件逻辑

修改后原错误消失,但样式组件中出现相同报错:

type TypeProps = {
    type: TypeName
}

export const Header = styled.View<TypeProps>`
    ${({theme, type}) => css`
        background-color: ${theme.colors.backgroundType[type]};
        height: 340px;
        padding: 20px;
        flex-direction: row;
        align-items: center;
        position: relative;
    `}  
`

报错行:background-color: ${theme.colors.backgroundType[type]};,提示Type 'TypeName' cannot be used as an index type。

尝试将type改为type['name']或type.name后报错消失,但应用无法正常访问类型。传递类型的组件代码:

<S.Header type={pokemon.types[0].type.name} >

解决方案

核心问题定位

你的TypeName定义是对象类型,但实际需要的是字符串字面量联合类型。colors.type的键是字符串字面量,用对象作为索引必然触发报错。

步骤1:修正TypeName类型定义

将TypeName改为字符串字面量联合类型:

type TypeName = 
    'bug' |
    'dark' |
    'dragon' |
    'electric' |
    'fairy' |
    'fighting' |
    'fire' |
    'flying' |
    'ghost' |
    'grass' |
    'ground' |
    'ice' |
    'normal' |
    'poison' |
    'psychic' |
    'rock' |
    'steel' |
    'water';

步骤2:修正数据请求中的类型断言

currentType从types[0].type.name获取的是字符串,直接断言为修正后的TypeName即可:

const currentType = types[0].type.name as TypeName;
const color = colors.type[currentType]; // 不再报错

步骤3:修正样式组件的Props与使用

  1. 修正TypeProps类型:
type TypeProps = {
    type: TypeName; // 现在是字符串字面量类型
}
  1. 样式组件中直接使用type作为索引:
export const Header = styled.View<TypeProps>`
    ${({theme, type}) => css`
        background-color: ${theme.colors.backgroundType[type]};
        // 其他样式...
    `}  
`
  1. 传递props保持原有写法即可:
<S.Header type={pokemon.types[0].type.name} >

额外优化:自动推导类型避免不一致

通过keyof自动推导TypeName,避免手动维护类型与配置键不一致:

// 先定义colors配置,再推导类型
const colorsConfig = {
    colors: {
        type: {
            bug: '#8CB230',
            dark: '#58575F',
            // ...其他颜色配置
        },
    }
}

type TypeName = keyof typeof colorsConfig.colors.type;

后续修改colors.type的键时,TypeName会自动更新,减少维护成本。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:35:16