TypeScript条件类型-筛选出只读属性/仅选取所需属性

TypeScript条件类型-筛选出只读属性/仅选取所需属性,typescript,typescript2.8,conditional-types,Typescript,Typescript2.8,Conditional Types,使用TypeScript中的新条件类型(或者其他技术),是否有一种方法可以根据接口的修改器仅从接口中拾取某些属性?例如,拥有 interface I1 { readonly n: number s: string } 我想在前一个类型的基础上创建一个新类型,如下所示: interface I2 { s: string } 2018-10更新:已发现可以检测只读字段(使下面删除的段落无效),如所示。以下是构建它的方法: type IfEquals<X, Y, A=

使用TypeScript中的新条件类型(或者其他技术),是否有一种方法可以根据接口的修改器仅从接口中拾取某些属性?例如,拥有

interface I1 {
    readonly n: number
    s: string
}
我想在前一个类型的基础上创建一个新类型,如下所示:

interface I2 {
    s: string
}
2018-10更新:已发现可以检测
只读
字段(使下面删除的段落无效),如所示。以下是构建它的方法:

type IfEquals<X, Y, A=X, B=never> =
  (<T>() => T extends X ? 1 : 2) extends
  (<T>() => T extends Y ? 1 : 2) ? A : B;

type WritableKeys<T> = {
  [P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, P>
}[keyof T];

type ReadonlyKeys<T> = {
  [P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, never, P>
}[keyof T];
万岁

对于
只读
,我认为您无法提取这些内容。我曾经做过,但那是不可能的;我认为一切都没有改变

因为,您始终可以将
{readonly n:number}
分配给
{n:number}
,反之亦然。因此,明显的TSv2.8条件类型检查不起作用。例如,如果认为
{n:number}
不可分配给
{readonly n:number}
,则可以执行以下操作:

//不起作用,请不要尝试此操作
类型ExcludeReadonlyProps=拾取

type I2=ExcludeReadonlyProps//应该是{s:string}但是是{}是的,我也在看这个,不要认为有一种方法可以基于readonlyVery创建任何类型的不兼容,非常有趣,谢谢。现在我又想到了两个小问题:1)如果编译器中添加了
--enforceReadonlyAssignability
之类的内容,您认为您的类型可以工作吗?以及2)其他修饰符呢,例如可选修饰符
?如果将来有人发现此线程,则可能会滥用条件类型的可分配性规则。(我想理论上我应该在这里发布一个答案,因为这个问题最受欢迎,然后以重复的形式结束另一个问题?我不介意。)@MattMcCutchen哇,太好了!我将编辑此答案。@Spencer我看到编辑已被其他人拒绝,但我想解释为什么需要
-?
:在
--strictNullChecks
模式下,可选属性会自动附加到其值类型中。由于过滤器是一个,默认行为是将可选属性转换为可选属性。假设您希望筛选器生成类似于
“foo”|“bar”
的内容,而不是
“foo”|“bar”|未定义的
,则需要显式删除可选修饰符。
interface I1 {
    readonly n: number
    s: string
}

type I2 = Pick<I1, WritableKeys<I1>>; 
// equivalent to { s: string; }