TypeScript为对象子属性指定类型报错及写法优化咨询
TypeScript为对象子属性指定类型的问题解析
报错原因
你写的foo.bar:Item = { name: 'name' }是错误语法:
- TypeScript的类型注解(
:后跟类型)只能用在变量声明阶段(比如let bar: Item = ...),赋值语句中不能给已有属性添加这种形式的类型标注。 - 报错提示
'Item' only refers to a type, but is being used as a value here,是因为TypeScript把你写的foo.bar:Item里的Item当成了运行时的值,但Item是一个接口类型,只存在于编译阶段,不是实际的JS值,所以触发错误。
正确为foo.bar指定类型的方式
最佳方案:提前完整定义接口
不要先声明空接口再事后扩展,一开始就把接口的结构定义清楚,TypeScript会自动校验赋值的类型:
interface Item { name: string } // 直接定义包含bar属性的Foo接口,明确bar的类型为Item(可选) interface Foo { bar?: Item } // 声明变量时指定Foo类型 const foo: Foo = {}; // 直接赋值,TS会自动检查是否符合Item类型 foo.bar = { name: 'name' };
若需扩展接口(不推荐)
如果一定要先声明空接口再扩展,也可以通过类型断言或让TS自动推断:
interface Foo {} const foo: Foo = {}; // 扩展Foo接口,指定bar的类型 interface Foo { bar?: Item } interface Item { name: string } // 方式1:TS根据扩展后的接口自动校验,无需断言 foo.bar = { name: 'name' }; // 方式2:显式类型断言(仅在TS无法自动推断时使用) foo.bar = { name: 'name' } as Item;
关于类型断言的位置问题
不能把as Item放在foo.bar =附近,类型断言as Type只能跟在被断言的值的后面,用来告诉TypeScript该值的类型。如果想提升可读性,可以用以下两种方式:
- 先把值赋值给带类型注解的变量,再赋值给
foo.bar:
const barItem: Item = { name: 'name' }; foo.bar = barItem;
- 回到最佳方案:提前完整定义接口,让TS自动校验类型,不需要额外的断言,代码可读性最高。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

