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

TypeScript条件类型:过滤只读属性/按修饰符选取属性

如何用TypeScript过滤接口中的只读属性

当然可以做到!TypeScript的条件类型搭配映射类型修饰符,完全能帮你从接口中筛选出非只读属性,生成新的类型。下面我给你具体实现和原理说明:

方法一:先提取可写属性名,再选取属性

首先我们可以定义一个辅助类型,用来提取接口中所有**可写(非只读)**的属性名:

// 提取所有可写属性的键名
type MutableKeys<T> = {
  [K in keyof T]-?: 
    { [P in K]: T[P] } extends { -readonly [P in K]: T[P] } 
      ? K 
      : never;
}[keyof T];

然后用Pick工具类型,从原接口中选取这些可写属性:

// 原接口
interface I1 { 
  readonly n: number; 
  s: string 
}

// 生成过滤后的类型I2
type I2 = Pick<I1, MutableKeys<I1>>;

// 此时I2的类型等价于:
// interface I2 { s: string }

方法二:直接在映射类型中过滤

如果你想更简洁一点,可以把逻辑合并到一个映射类型里:

// 直接移除所有只读属性的类型工具
type RemoveReadonly<T> = {
  [K in keyof T as 
    { [P in K]: T[P] } extends { -readonly [P in K]: T[P] } 
      ? K 
      : never
  ]: T[K];
};

// 应用到你的接口上
type I2 = RemoveReadonly<I1>;

原理说明

这里的核心逻辑依赖两个TypeScript特性:

  1. 映射类型修饰符-readonly:用来移除属性的readonly标记,比如{ -readonly [P in K]: T[P] }会把属性K的只读特性去掉。
  2. 条件类型判断:我们对比“原属性类型”和“移除只读后的属性类型”——如果两者兼容,说明这个属性本来就不是只读的(移除readonly后没有变化),就保留这个属性名;反之则是只读属性,排除掉。

需要注意的是,这个方案要求你使用TypeScript 2.8及以上版本,因为条件类型是在2.8版本引入的,映射类型修饰符也是同期支持的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:17:18