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

TypeScript中如何根据嵌套Input类型定义正确的Output泛型?

问题原因分析

你遇到的output.hello类型为never的问题,核心在于两个点:

  1. 类型拓宽导致的模糊性
    当你显式把input声明为Input类型时,TypeScript会将每个属性的类型自动拓宽为Property | Input联合类型,而非具体的{ type: "string" }或嵌套Input结构。这种模糊的联合类型无法匹配Output<T>中的任何条件分支,最终落到never。

  2. 条件判断逻辑的覆盖不足
    原Output类型的条件判断顺序和逻辑,没有正确处理Property | Input这种联合类型:

    • T[Key] extends { type: "string" }:因为联合类型包含无type字段的Input,条件不成立;
    • T[Key] extends { type: "number" }:同理,联合类型包含Input,条件不成立;
    • T[Key] extends Input:联合类型包含有type字段的Property,条件也不成立;
      最终所有分支都不匹配,返回never。
解决方案

方案1:保留具体类型推断,约束结构而非直接声明类型

去掉input的Input类型声明,用satisfies关键字确保结构符合Input规范的同时,让TypeScript保留每个属性的具体类型信息:

export type Property = { type: "string" } | { type: "number" };
export type Input = { [key: string]: Property | Input };

export type Output<T extends Input> = {
  [Key in keyof T]: 
    T[Key] extends Property 
      ? T[Key]["type"] extends "string" ? string : number
      : T[Key] extends Input ? Output<T[Key]> : never
};

// 用satisfies约束结构,保留具体类型推断
const input = {
  hello: {
    type: "string",
  },
  first: {
    second: {
      type: "number"
    }
  }
} satisfies Input;

function processInput<T extends Input>(input: T): Output<T> {
  const result: Record<string, any> = {};
  for (const key in input) {
    const val = input[key];
    if ("type" in val) {
      result[key] = val.type === "string" ? "" : 0; // 示例赋值逻辑
    } else {
      result[key] = processInput(val);
    }
  }
  return result as Output<T>;
}

const output = processInput(input);
console.log(output.hello); // 类型为string,正常访问
console.log(output.first.second); // 类型为number,正常访问

方案2:调整Output类型的判断逻辑

修改Output类型,优先判断是否为Property类型(通过type字段区分),再处理嵌套的Input结构,确保联合类型能被正确分配:

export type Property = { type: "string" } | { type: "number" };
export type Input = { [key: string]: Property | Input };

// 先判断是否为Property,再处理嵌套Input
export type Output<T extends Input> = {
  [Key in keyof T]: 
    T[Key] extends { type: infer U }
      ? U extends "string" ? string : number
      : T[Key] extends Input ? Output<T[Key]> : never
};

这种写法通过infer U提取type字段的具体值,能更精准地匹配联合类型中的分支。

内容的提问来源于stack exchange,提问作者pastel-bucket

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:00:56