TypeScript中如何检查传入参数是否为自定义interface类型?
报错翻译
“'IComic'仅指代一个类型,但此处被当作值使用。”
问题根源
TypeScript 的 interface 是编译时专属类型,编译成 JavaScript 后会被彻底移除,运行时根本不存在对应的实体。你用 typeof A 这种写法,相当于试图引用一个不存在的运行时变量,自然会报错。
解决办法
要实现根据对象结构分支处理,得用运行时能生效的判断逻辑,下面是几种实用方案:
1. 用in操作符做简单判断
直接检查对象是否包含目标属性,TypeScript 会自动帮你收窄类型:
interface A { string: string } interface B { number: number } interface C { boolean: boolean } function doSomething(item: A | B | C) { if ('string' in item) { // 这里 TypeScript 会自动识别 item 是 A 类型 console.log('处理A类型:', item.string); } else if ('number' in item) { // 自动识别为 B 类型 console.log('处理B类型:', item.number); } else if ('boolean' in item) { // 自动识别为 C 类型 console.log('处理C类型:', item.boolean); } }
2. 自定义类型守卫函数
如果属性名可能重复,或者需要更严格的类型校验,可以写专门的守卫函数:
interface A { string: string } interface B { number: number } interface C { boolean: boolean } // 判断是否为 A 类型 function isA(item: unknown): item is A { return typeof item === 'object' && item !== null && 'string' in item && typeof (item as A).string === 'string'; } // 判断是否为 B 类型 function isB(item: unknown): item is B { return typeof item === 'object' && item !== null && 'number' in item && typeof (item as B).number === 'number'; } // 判断是否为 C 类型 function isC(item: unknown): item is C { return typeof item === 'object' && item !== null && 'boolean' in item && typeof (item as C).boolean === 'boolean'; } function doSomething(item: unknown) { if (isA(item)) { console.log('处理A类型:', item.string); } else if (isB(item)) { console.log('处理B类型:', item.number); } else if (isC(item)) { console.log('处理C类型:', item.boolean); } }
3. 给接口加类型标识(最稳妥)
如果能修改接口定义,建议给每个接口加一个唯一的type字段,形成可区分联合类型,代码可读性和安全性最高:
interface A { type: 'A'; // 唯一标识 string: string } interface B { type: 'B'; number: number } interface C { type: 'C'; boolean: boolean } type Item = A | B | C; function doSomething(item: Item) { switch (item.type) { case 'A': console.log('处理A类型:', item.string); break; case 'B': console.log('处理B类型:', item.number); break; case 'C': console.log('处理C类型:', item.boolean); break; } }
内容的提问来源于stack exchange,提问作者ludinj
相关产品推荐
相关产品推荐

