Angular @Input传参遇TS错误:string无法赋值给指定联合类型
Angular @Input 装饰器传递参数时的TypeScript类型错误问题
在使用Angular的@Input装饰器传递参数时,出现了TypeScript类型不兼容错误,但相同逻辑在普通TypeScript代码中可正常运行。
子组件(child.component.ts)代码
import { Input, Component } from '@angular/core'; @Component({ selector: 'app-child', // 组件其他配置 }) export class ChildComponent { @Input() customColumns: { name: string; index: number; type: 'icon' | 'image' | 'link' | 'button'; icon?: any; url?: string; }[] = []; indexList: number[] = []; }
父组件(parent.component.ts)代码
// 假设已导入faSave等图标 import { Component } from '@angular/core'; @Component({ selector: 'app-parent', // 组件其他配置 }) export class ParentComponent { customColumns = [ { name: 'permissions', index: 7, type: 'icon', icon: faSave }, { name: 'price list', index: 6, type: 'link', icon: faArrowDownWideShort }, { name: 'details', index: 5, type: 'button', icon: faArrowUpWideShort }, ]; }
父组件模板(parent.component.html)
<app-child [customColumns]="customColumns"> </app-child>
错误提示
Types of property 'type' are incompatible.
Type 'string' is not assignable to type '"button" | "link" | "image" | "icon"'.
普通TypeScript代码(无报错)
let customColumns: { name: string; index: number; type: 'icon' | 'image' | 'link' | 'button'; icon?: any; url?: string; }[] = []; customColumns = [ { name: 'permissions', index: 7, type: 'link', icon: '' }, { name: 'price list', index: 6, type: 'icon', icon: faArrowDownWideShort, }, { name: 'details', index: 5, type: 'icon', icon: faArrowUpWideShort }, ];
项目依赖版本
"@angular/cli": "~14.2.7",
"typescript": "~4.7.2"
解决方案及原因
问题根源
父组件中customColumns变量未显式指定类型,TypeScript自动将type字段推断为宽泛的string类型,而非子组件要求的字面量联合类型。Angular模板的类型检查(严格模式下更严格)会严格校验@Input的类型匹配,因此抛出错误。而普通TS代码中,变量一开始就指定了类型,TypeScript会直接校验赋值的兼容性,不会出现推断偏差。
方案1:给父组件变量显式指定类型
先定义复用的类型别名,再给变量指定类型:
import { Component } from '@angular/core'; // 导入图标... type CustomColumn = { name: string; index: number; type: 'icon' | 'image' | 'link' | 'button'; icon?: any; url?: string; }; @Component({ selector: 'app-parent', // 组件配置 }) export class ParentComponent { customColumns: CustomColumn[] = [ { name: 'permissions', index: 7, type: 'icon', icon: faSave }, { name: 'price list', index: 6, type: 'link', icon: faArrowDownWideShort }, { name: 'details', index: 5, type: 'button', icon: faArrowUpWideShort }, ]; }
方案2:使用as const断言字面量类型
通过as const让TypeScript保留字段的字面量类型,避免被推断为string:
export class ParentComponent { // 单个字段断言 customColumns = [ { name: 'permissions', index: 7, type: 'icon' as const, icon: faSave }, { name: 'price list', index: 6, type: 'link' as const, icon: faArrowDownWideShort }, { name: 'details', index: 5, type: 'button' as const, icon: faArrowUpWideShort }, ]; // 或者对整个数组断言 customColumns = [ { name: 'permissions', index: 7, type: 'icon', icon: faSave }, { name: 'price list', index: 6, type: 'link', icon: faArrowDownWideShort }, { name: 'details', index: 5, type: 'button', icon: faArrowUpWideShort }, ] as const; }
内容的提问来源于stack exchange,提问作者Md. Mahadad Hossain
相关产品推荐
相关产品推荐

