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

Angular Strict模式下TypeScript类型赋值报错原因与解决方案

TypeScript TS2322错误分析与解决

类型与函数定义

export interface LanguageEditInfoDto {
    canEdit: boolean;
    label: string;
    useDudenLang: boolean;
}
export type UILanguageEditInfoDto = LanguageEditInfoDto & {
    isFormValid: boolean;
};

function setLanguages(languages: Record<string, LanguageEditInfoDto>) {
    const langState: Record<string, UILanguageEditInfoDto> = {};
    for (const langCode in languages) {
        langState[langCode] = {
            isFormValid: true,
            ...languages[langCode],
        };
    }
}

错误信息

TS2322: Type { canEdit?: boolean | undefined; label?: string | undefined; useDudenLang?: boolean | undefined; isFormValid: true; } is not assignable to type UILanguageEditInfoDto
Type { canEdit?: boolean | undefined; label?: string | undefined; useDudenLang?: boolean | undefined; isFormValid: true; } is not assignable to type LanguageEditInfoDto

错误原因

问题出在for...in循环中对languages[langCode]的类型推断:

  • Record<string, LanguageEditInfoDto>的索引签名规定,任意字符串键都可能对应值或undefined,TypeScript不会因为langCode来自for...in循环就自动推断languages[langCode]一定存在,因此它的类型被判定为LanguageEditInfoDto | undefined。
  • 当展开一个可能为undefined的对象时,TypeScript会将原接口的所有属性标记为可选(因为如果原对象是undefined,展开后不会包含这些属性),最终合并后的对象类型变成{isFormValid: true} & Partial<LanguageEditInfoDto>,与要求的UILanguageEditInfoDto(必填属性+isFormValid)类型不兼容。

解决方法

有以下几种可行的解决方式:

1. 使用非空断言操作符!

明确告诉TypeScriptlanguages[langCode]一定存在:

function setLanguages(languages: Record<string, LanguageEditInfoDto>) {
    const langState: Record<string, UILanguageEditInfoDto> = {};
    for (const langCode in languages) {
        langState[langCode] = {
            isFormValid: true,
            ...languages[langCode]!,
        };
    }
}

2. 类型断言

直接断言languages[langCode]的类型为LanguageEditInfoDto:

function setLanguages(languages: Record<string, LanguageEditInfoDto>) {
    const langState: Record<string, UILanguageEditInfoDto> = {};
    for (const langCode in languages) {
        langState[langCode] = {
            isFormValid: true,
            ...languages[langCode] as LanguageEditInfoDto,
        };
    }
}

3. 改用Object.entries遍历

通过键值对遍历,直接获取明确的LanguageEditInfoDto类型值:

function setLanguages(languages: Record<string, LanguageEditInfoDto>) {
    const langState: Record<string, UILanguageEditInfoDto> = {};
    for (const [langCode, lang] of Object.entries(languages)) {
        langState[langCode] = {
            isFormValid: true,
            ...lang,
        };
    }
}

4. 添加空值检查(冗余但安全)

通过条件判断缩小类型范围,虽然逻辑上不会触发,但能让TypeScript正确推断类型:

function setLanguages(languages: Record<string, LanguageEditInfoDto>) {
    const langState: Record<string, UILanguageEditInfoDto> = {};
    for (const langCode in languages) {
        const lang = languages[langCode];
        if (!lang) continue;
        langState[langCode] = {
            isFormValid: true,
            ...lang,
        };
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:08:17