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

如何生成可为指定类型设置部分默认值的泛型类型?解决TS类型报错

解决TypeScript类型不兼容问题:为genStruct生成正确的泛型类型

问题分析

你遇到的错误核心是:genStruct返回的Partial<Responsive<T>>会让每个断点属性变成可选类型(可能为undefined),但Default类型要求所有断点属性必须是NestedProps(不允许undefined),导致类型不匹配。

解决方案

我们需要让genStruct根据传入的具体断点列表,返回包含这些断点的必选属性的类型,而非全可选的Partial类型。具体修改如下:

修改后的代码

type Breakpoint = "sm" | "md" | "lg"

// 新增泛型参数B,捕获传入的断点数组的字面量类型
export const genStruct = <T extends object, B extends Breakpoint[]>(
    defaultValue: T,
    breakpoints: B,
): Pick<Responsive<T>, B[number]> => {
    return breakpoints.reduce((acc, breakpoint) => {
        acc[breakpoint] = Object.keys(defaultValue).length === 0
            ? ('' as T extends Record<string, never> ? '' : T) // 替换any,更安全的类型断言
            : { ...defaultValue }
        return acc
    }, {} as Pick<Responsive<T>, B[number]>)
}

type NestedProps = {
    rows: string
    cols: string
}

type Responsive<T> = {
    [key in Breakpoint]: T
}

type Default = Responsive<NestedProps>

// 调用时给断点数组加as const,让TypeScript推断具体的字面量类型
const some_value: Default = {
    sm: {
        rows: '',
        cols: '',
    },
    ...genStruct({
        rows: '',
        cols: '',
    }, ['md', 'lg'] as const)
}

关键修改说明

  1. 泛型参数B extends Breakpoint[]:让TypeScript捕获传入的断点数组的具体字面量类型(比如['md', 'lg'] as const会被推断为readonly ["md", "lg"])。
  2. 返回类型Pick<Responsive<T>, B[number]>:从Responsive<T>中选取B[number]对应的断点键,这些键的属性是必选类型,完全匹配Default的要求,不会出现undefined。
  3. as const断言:调用genStruct时给断点数组添加该断言,确保TypeScript不会把数组模糊推断为Breakpoint[],而是保留具体的元素类型。
  4. 替换any类型断言:将('' as any)改为更安全的条件类型断言,减少类型漏洞。

效果验证

修改后,genStruct返回的对象中md和lg属性会被推断为必选的NestedProps类型,与Default的结构完全兼容,TypeScript不再抛出类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:00:08