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

如何基于接口数组属性值对另一属性进行TypeScript类型校验?

解决TypeScript中基于数组属性值的类型校验问题

问题根源

你当前的代码里,tabs被显式标注为RootLayoutTab[],这会让TypeScript忽略数组元素中id的具体字面量值(比如'database'、'gateways'),只把id的类型识别为宽泛的string。因此defaultTab的类型被推断为string,自然不会对无效值触发校验错误。

修复方案

方案1:使用const断言保留字面量类型

去掉tabs的显式类型标注,改用as const让TypeScript推导每个元素的精确字面量类型:

export interface RootLayoutTab {
    id: string;
    title: string;
}

interface RootLayoutProps<T extends readonly RootLayoutTab[]> {
    tabs: T;
    // 提取数组元素中id的联合类型
    defaultTab: T[number]['id'];
}

// 用as const断言保留字面量类型,同时满足RootLayoutTab的结构约束
const tabs = [
    { id: 'database', title: 'Database' },
    { id: 'gateways', title: 'Gateways' },
] as const;

const props: RootLayoutProps<typeof tabs> = {
    tabs,
    defaultTab: 'database-test', // 这里会触发类型错误,符合预期
};

方案2:通过泛型函数约束数组类型

如果需要强制tabs必须符合RootLayoutTab的结构,同时保留字面量类型,可以用泛型函数来创建数组:

export interface RootLayoutTab {
    id: string;
    title: string;
}

interface RootLayoutProps<T extends RootLayoutTab[]> {
    tabs: T;
    defaultTab: T[number]['id'];
}

// 泛型函数约束数组元素符合RootLayoutTab,同时推导字面量类型
function createTabs<T extends RootLayoutTab[]>(tabs: [...T]) {
    return tabs;
}

const tabs = createTabs([
    { id: 'database', title: 'Database' },
    { id: 'gateways', title: 'Gateways' },
]);

const props: RootLayoutProps<typeof tabs> = {
    tabs,
    defaultTab: 'database-test', // 触发类型错误,符合预期
};

原理说明

  • 两种方案的核心都是让TypeScript保留数组中id的具体字面量值,而不是将其宽泛化为string。
  • T[number]['id']语法用于提取数组类型T中所有元素的id属性,形成联合类型(比如'database' | 'gateways'),这样defaultTab就只能接受这个联合类型中的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:53:18