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

如何用TypeScript泛型强耦合Grid与Grid.Item的Props类型?

实现Grid与Grid.Item的类型安全强耦合

要实现Grid的gridTemplateAreas和Grid.Item的gridArea强类型绑定,核心是从gridTemplateAreas字符串中提取合法的区域名称,再限制Grid.Item只能使用这些名称。以下是具体实现步骤:

1. 定义区域名称解析的类型工具

通过TypeScript模板字符串类型,从gridTemplateAreas格式的字符串中提取所有唯一的区域名称:

// 提取单个引号内的区域名称列表
type ExtractAreaNames<T extends string> = 
  T extends `'${infer Content}'` ? Content extends `${infer Area} ${infer Rest}` 
    ? Area | ExtractAreaNames<`'${Rest}'`> 
    : Content 
  : never;

// 解析整个gridTemplateAreas字符串,去重后得到合法区域名称的联合类型
type ParseGridAreas<T extends string> = 
  T extends `${infer FirstPart} ${infer Rest}` 
    ? ExtractAreaNames<`'${FirstPart}'`> | ParseGridAreas<Rest> 
    : ExtractAreaNames<`'${T}'`>;

2. 定义泛型组件Props

让GridProps成为泛型,接收区域名称的联合类型;GridItemProps则依赖这个联合类型,限制gridArea只能是其中的成员:

import React from 'react';

// Grid组件Props,泛型T是区域名称的联合类型
interface GridProps<T extends string> {
  gridTemplateAreas: T;
  children: React.ReactNode;
}

// Grid.Item组件Props,依赖Grid的区域类型T
interface GridItemProps<T extends string> {
  gridArea: T;
  children: React.ReactNode;
}

3. 实现泛型Grid组件

将Grid.Item作为Grid的静态属性,继承Grid的泛型参数,确保类型联动:

// 定义Grid组件,泛型T代表所有合法的区域名称
const Grid = <T extends string>(props: GridProps<T>) => {
  return (
    <div style={{ display: 'grid', gridTemplateAreas: props.gridTemplateAreas }}>
      {props.children}
    </div>
  );
};

// 定义Grid.Item,复用Grid的泛型T,确保gridArea只能是T中的成员
Grid.Item = <T extends string>(props: GridItemProps<T>) => {
  return <div style={{ gridArea: props.gridArea }}>{props.children}</div>;
};

4. 使用示例与类型校验

使用时,TypeScript会自动从gridTemplateAreas中推导合法的区域名称,若Grid.Item使用了不存在的名称会直接报错:

// 正确用法,所有gridArea都在gridTemplateAreas中定义
<Grid gridTemplateAreas="'item1 item2' 'item3 item3'">
  <Grid.Item gridArea="item1">1st item of grid</Grid.Item>
  <Grid.Item gridArea="item2">2nd item of grid</Grid.Item>
  <Grid.Item gridArea="item3">3rd item of grid</Grid.Item>
</Grid>

// 错误用法:TypeScript会报错,因为"item4"不在gridTemplateAreas的定义中
<Grid gridTemplateAreas="'item1 item2'">
  <Grid.Item gridArea="item4">Invalid item</Grid.Item>
</Grid>

补充说明

  • 上述类型工具支持标准的gridTemplateAreas格式(用单引号包裹行,空格分隔列);
  • 若需要支持无引号的简化格式,可以调整ExtractAreaNames的匹配逻辑;
  • 泛型推导是自动完成的,无需手动传入类型参数,使用体验和普通组件一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:58:20