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

TypeScript条件联合类型失效:'string'无法赋值给'never'报错排查

问题原因及解决方法:Type 'string' is not assignable to type 'never'

问题场景

定义了用于推导对象指定路径属性类型的GetFieldType条件类型,以及基于它的Route类型,但使用Route<Item>时出现类型错误:Type 'string' is not assignable to type 'never'.ts(2322)。代码如下:

type GetFieldType<TObject, TPath> = TPath extends keyof TObject ? TObject[TPath] : undefined;

type Route<TObject> = {
  [TPath in string]: Extract<GetFieldType<TObject, TPath>, boolean | number | string>;
};

interface Item {
  foo: string
}

const r: Route<Item> = {
  "foo": "string"  // 报错:Type 'string' is not assignable to type 'never'.(2322)
}

问题原因

  1. Route类型的键遍历范围错误:[TPath in string]表示遍历所有string类型的键,而非目标对象TObject的键集合。
  2. 条件类型的泛型推断失效:当TPath是任意string时,TypeScript无法将具体的键(比如"foo")与泛型参数TPath关联。对于绝大多数string类型的键(非TObject的键),GetFieldType返回undefined,经过Extract处理后得到never;即使是TObject的键,由于TPath是任意string而非具体的keyof TObject,TypeScript也无法推断出正确的属性类型,最终整个Route<TObject>的所有属性类型都被推断为never,导致赋值时类型不匹配。

解决方法

方法一:限制Route的键为目标对象的键集合

如果只需要支持目标对象的一级键,直接将Route的键遍历范围改为keyof TObject,这样每个键对应的类型会被正确推断:

type GetFieldType<TObject, TPath> = TPath extends keyof TObject ? TObject[TPath] : undefined;

// 遍历keyof TObject而非所有string
type Route<TObject> = {
  [TPath in keyof TObject]: Extract<GetFieldType<TObject, TPath>, boolean | number | string>;
};

interface Item {
  foo: string
}

const r: Route<Item> = {
  "foo": "string" // 类型匹配,无报错
}

方法二:支持嵌套路径的扩展(可选)

如果需要支持嵌套属性路径(比如"foo.bar"),需要修改GetFieldType来处理路径拆分,同时调整Route的键类型为合法的路径字符串:

// 处理嵌套路径的GetFieldType
type GetFieldType<TObject, TPath extends string> = 
  TPath extends `${infer K}.${infer Rest}` 
    ? K extends keyof TObject 
      ? GetFieldType<TObject[K], Rest> 
      : undefined 
    : TPath extends keyof TObject 
      ? TObject[TPath] 
      : undefined;

// 定义合法路径类型(这里简化为string,可根据需要限制为TObject的所有可能路径)
type Route<TObject> = {
  [TPath in string]: Extract<GetFieldType<TObject, TPath>, boolean | number | string>;
};

interface Item {
  foo: string;
  bar: {
    baz: number;
  };
}

const r: Route<Item> = {
  "foo": "string", // 正确
  "bar.baz": 123 // 正确
}

注意:方法二中Route的键仍为string,但TypeScript在具体赋值时会根据GetFieldType推断对应类型,不过这种方式无法在编译阶段限制键必须是合法路径,若需要严格限制路径,可进一步实现Paths类型来生成所有合法路径集合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:50:20