表格插槽里的 row 是宽类型:TS7053
后台表格的列要用插槽渲染,代码很普通:
<el-table-column prop="status">
<template #default="{ row }">
{{ statusText[row.status] }}
</template>
</el-table-column>
报错 TS7053:无法用 string 类型的表达式索引 { } 这个类型。
原因拆开看是两层。第一层,组件库给插槽作用域的类型是宽的,row 上有什么它不知道,row.status 推出来是 string 而不是我那几个枚举值之一。第二层,statusText 是个对象字面量,它的类型只有那几个键,用 string 去索引就报错。
三种解法我都试过:
(statusText as Record<string, string>)[row.status] —— 有效,但每个插槽都要写一次断言,很脏。
给 statusText 加显式类型 Record<Status, string>,同时把 row 断言成 { status: Status }。两处断言,比上面少一个,但还是断言。
我最后用的:把映射写成按字段值的函数,在 script 里定义好,插槽只调它。
type Status = 'draft' | 'published'
const statusText: Record<Status, string> = { draft: '草稿', published: '已发布' }
const textOf = (s: Status) => statusText[s]
插槽里写 textOf(row.status as Status)。断言只剩一处,而且新增状态时编译期会在 statusText 上报缺键——这才是我要的效果:错误暴露在字典那一行,而不是散在模板里。
还有一个 TS2345:给组件传 :data="list",list 是接口返回的 any[],赋给要求 Article[] 的 prop 时不报错,因为 any 兼容一切。所以接口层返回类型才是根,表格这层只是把问题显形了。