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

如何从TypeScript字符串联合类型中移除string类型?

如何实现移除联合类型中的string并保留字面量类型?

我从API生成的TypeScript类型里,遇到了这样的联合类型:

type Foo = 'foo' | 'bar' | string

我需要移除其中的宽泛string类型,只保留'foo' | 'bar'这类字符串字面量,也就是实现一个RemoveStringButKeepConstants类型,让:

type NarrowFoo = RemoveStringButKeepConstants<Foo>
//    ^? 'foo' | 'bar' 

之前尝试的两种方案都没达到预期:

type Attempt1 = Exclude<Foo, string> // 结果是never,无法保留字面量
type Attempt2 = `${Foo}` // 结果还是string,没有收窄类型

也考虑过const类型参数,但不知道如何运用。


解决方案

可以利用TypeScript条件类型的特性,通过判断类型是否为宽泛的原始类型来过滤:

type RemoveStringButKeepConstants<T> = T extends string 
  ? (string extends T ? never : T) 
  : T;

// 验证效果
type Foo = 'foo' | 'bar' | string;
type NarrowFoo = RemoveStringButKeepConstants<Foo>; 
// NarrowFoo 最终类型为 'foo' | 'bar'

原理说明

  • 当泛型T匹配到宽泛的string时,string extends T条件成立,返回never,从而将其排除。
  • 当T匹配到字符串字面量(如'foo')时,string extends 'foo'不成立,直接返回T本身,保留字面量类型。

如果需要支持更多原始类型(比如排除宽泛number/boolean,保留对应字面量),可以扩展这个类型:

type RemovePrimitiveButKeepLiterals<T> = 
  T extends string ? (string extends T ? never : T) :
  T extends number ? (number extends T ? never : T) :
  T extends boolean ? (boolean extends T ? never : T) :
  T;

// 测试混合类型
type Mixed = 'a' | 123 | boolean | string | number;
type Narrowed = RemovePrimitiveButKeepLiterals<Mixed>;
// Narrowed 类型为 'a' | 123 | true | false

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:13:22