TypeScript函数中如何判断参数实例类型?instanceof与typeof失效如何解决
问题原因
TypeScript 的interface仅存在于编译阶段,代码编译为JavaScript运行时,接口类型会被完全擦除。instanceof是原生JavaScript的运行时操作符,只能判断类的实例归属,typeof只能返回基础类型的判断结果,因此都无法识别你定义的Vehicle和Package接口类型。
解决方案
方案1:使用可辨识联合(推荐,适合未来扩展更多类型)
给所有要判断的接口新增一个固定的字符串字面量类型的公共字段作为类型标识:
interface Vehicle { type: 'vehicle' // 保留原有车辆相关字段 } interface Package { type: 'package' // 保留原有包裹相关字段 }
之后直接判断type字段即可完成类型区分,TypeScript还会自动完成类型收窄:
const renderItem: ListRenderItem<Vehicle | Package> = ({ item }) => ( <ModalSelectionItem topText={ item.type === 'vehicle' ? 'a' : 'b'} /> );
后续新增类型时,只要给新接口加对应type标识,新增判断分支即可,维护成本极低。你可以同时给泛型Props加上约束,避免后续传入不符合要求的类型:
interface Props<T extends { type: string }> { modalVisible: boolean, selectableData: T[], currentlySelectedIndex: number, onSelect: (selection: T) => void, onBackPressed: () => void }
方案2:自定义类型守卫(适合不能修改原有接口结构的场景)
如果不能修改原有接口的定义,你可以通过判断接口独有的字段来编写自定义类型守卫:
// 示例中假设Vehicle独有licensePlate字段,Package独有trackingNumber字段,可替换为实际业务的独有字段 function isVehicle(item: Vehicle | Package): item is Vehicle { return 'licensePlate' in item } function isPackage(item: Vehicle | Package): item is Package { return 'trackingNumber' in item }
在渲染时直接调用类型守卫函数即可:
const renderItem: ListRenderItem<Vehicle | Package> = ({ item }) => ( <ModalSelectionItem topText={ isVehicle(item) ? 'a' : 'b'} /> );
内容的提问来源于stack exchange,提问作者Keselme
相关产品推荐
相关产品推荐

