You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js具名插槽结合TypeScript的元组类型推断问题

Vue具名插槽与元组类型推断问题

Vue.js的具名插槽特性可用于覆盖指定插槽的默认渲染内容,组件内的实现方式如下:

<td v-for="(column, index) in tuple">
  <slot
    :name="slotName(column)" // string
    :value="getValue(item, column) as TupleValues<typeof tuple, typeof item>[index]
</slot>
</td>

在使用该组件时,可通过具名插槽自定义指定列的渲染:

<template #score="{ value }">
  // value 应为 TupleMap<typeof tuple, typeof item>['score']
  // score 是此前 slotName(column) 返回的插槽名
</template>

这是一种自定义指定插槽默认渲染内容的模式:columns是一个元组,用于定义表格的每一列,以及从数组项中获取对应值的键(该元组也可定义返回列自定义值的函数);数组中的每个元素代表一行数据。


元组值类型的类型定义

我们可以通过以下两个类型来获取每个元组元素的值类型:

TupleValues

type TupleValues<
  T extends Array<{ key: keyof U | string; value?: keyof U | string | ((...args: any[]) => any) }>,
  U
> = {
  [P in keyof T]: T[P]['key'] extends keyof U
    ? U[T[P]['key']]
    : T[P]['value'] extends keyof U
      ? U[T[P]['value']]
      : T[P]['value'] extends (...args: unknown[]) => unknown
        ? ReturnType<T[P]['value']>
        : never
}

TupleMap

type TupleMap<
  T extends Array<{ key: keyof U | string; value?: keyof U | string | ((...args: any[]) => any) }>,
  U
> = {
  [P in T[number] as P['key']]: P['key'] extends keyof U
    ? U[P['key']]
    : P['value'] extends keyof U
      ? U[P['value']]
      : P['value'] extends (...args: unknown[]) => unknown
        ? ReturnType<P['value']>
        : never
}

存在的问题

遗憾的是,使用v-for循环渲染插槽时,上述类型推断会失效。

如果不使用v-for,而是为每个元组索引手动定义插槽,虽然能从元组中推断出确切的插槽名和值类型,但这种方式无法适配任意数量的列:

<td>
  <slot
    :name="columnName(columns[0])" // 可从元组推断出确切的插槽名
    :value="getValue(item, column) as TupleValues<typeof tuple, typeof item>[0]" // 可从元组推断出确切的插槽值
  > <DefaultSlotRenderer /> </slot>
</td>
<td>
  <slot
    :name="columnName(columns[1])" // 可从元组推断出确切的插槽名
    :value="getValue(item, column) as TupleValues<typeof tuple, typeof item>[1]" // 可从元组推断出确切的插槽值
  > <DefaultSlotRenderer /> </slot>
</td>
<td>
  <slot
    :name="columnName(columns[2])" // 可从元组推断出确切的插槽名
    :value="getValue(item, column) as TupleValues<typeof tuple, typeof item>[2]" // 可从元组推断出确切的插槽值
  > <DefaultSlotRenderer /> </slot>
</td>

补充说明

事实证明,即使不使用v-for循环,该方案也无法生效,且问题并非出在类型定义上。建议将代码复制到本地运行以查看智能提示效果。


内容的提问来源于stack exchange,提问作者darkbasic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 05:47:03