Vue3 + TypeScript中检查自定义对象类型以实现组件动态渲染的方案咨询
Vue3 + TypeScript中检查自定义对象类型以实现组件动态渲染的方案咨询
我明白你遇到的问题啦——TypeScript的自定义类型是编译时的概念,到了运行时就不存在了,所以用typeof肯定没法直接判断CustomA这种自定义类型,这也是你看到那个TS报错的原因。下面给你几个实用的解决方案,你可以根据自己的场景选:
方案一:给自定义类型加标识字段(最推荐)
给你的CustomA和CustomB类型各加一个唯一的标识字段,比如type,这样在运行时就能通过这个字段来区分类型,同时还能让TS正确推导类型:
type CustomA = { type: 'CustomA' // 新增唯一标识字段 id: string title: string description: string status: 'Draft' | 'In Progress' | 'Completed' files: ProjectFiles[] users: string[] } type CustomB = { type: 'CustomB' // 对应CustomB的标识 // 你的CustomB原有字段 } // 定义props时简化为联合类型数组 const props = defineProps({ objectList: { type: Array as PropType<Array<CustomA | CustomB>>, required: true, }, }) // 现在可以直接通过type字段判断,TS也能正确识别类型 const isCustomAList = props.objectList.length > 0 && props.objectList[0].type === 'CustomA'
如果需要更严谨的类型判断,还可以写自定义类型守卫函数:
function isCustomA(item: CustomA | CustomB): item is CustomA { return item.type === 'CustomA' } // 使用时 if (props.objectList.length > 0 && isCustomA(props.objectList[0])) { // 这里TS会自动识别item为CustomA类型 }
方案二:检查对象的特征属性
如果不想加标识字段,可以通过检查对象是否包含某个独有的属性来判断类型。比如CustomA有status字段,而CustomB没有,就可以这么写:
function isCustomA(item: CustomA | CustomB): item is CustomA { return 'status' in item && typeof item.status === 'string' } // 然后用这个函数判断 const isCustomAList = props.objectList.length > 0 && isCustomA(props.objectList[0])
不过这种方式要注意:如果两个类型有重叠的属性,可能会判断不准确,所以只适合属性差异明显的场景。
方案三:拆分不同类型的Props
就你提到的思路,把objectList拆成两个独立的props:
const props = defineProps({ customAList: { type: Array as PropType<Array<CustomA>>, default: () => [], }, customBList: { type: Array as PropType<Array<CustomB>>, default: () => [], }, }) // 判断哪个列表有内容 const useCustomA = props.customAList.length > 0
这种方式逻辑最简单,适合两种类型的列表不会同时传入的场景,代码可读性也很高。
总结一下:优先选方案一,因为它最清晰、最可靠;如果不能加标识字段,再考虑方案二;如果场景简单,方案三也是不错的选择。
内容来源于stack exchange
相关产品推荐
相关产品推荐

