在具有索引类型签名的类上使用 Omit 类型会导致不需要最少的属性 [英] Using Omit type on classes with a index type signature results in minimum properties not being required
问题描述
我有一个类,它具有一些必需的属性,然后可以具有由扩展该属性的类定义的其他属性(或者无论如何,一些我不知道的额外属性).
I have a class which has some mandatory properties and can then have other properties defined by classes extending this one (or anyway, some extra properties I don't know about).
现在我尝试在其上使用 Omit
类型,定义为
Now I'm trying to use Omit
type on it, defined as
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
如果我们定义类为
class Thing {
constructor(
public id: number,
public name: string,
public description: string
) {}
}
我们可以做 Omit
并获得正确的类型推断为 Pick
We can do Omit<Thing, 'id'>
and get the right type inference as Pick<Thing, "name" | "description">
如果我们在类中添加一个 [index: string]: any
以支持未知属性并重试 Omit
,现在推断类型将是 Pick
.
If we add a [index: string]: any
to the class to support unknown properties and retry Omit<Thing, 'id'>
, now the inferred type will be Pick<Thing, string | number>
.
class Thing {
constructor(
public id: number,
public name: string,
public description: string
) {}
[index: string]: any;
}
这真的没有意义:当我使用类键入时,即使定义了 [index: string]: any;
也需要所有属性,为什么它会变成 松散类型时省略其属性之一?我希望返回类型仍然是 Pick
.
This doesn't really make sense: when I type using the class, all properties are required even when a [index: string]: any;
is defined, why would it become a looser type when omitting one of its properties? I would expect the return type to still be Pick<Thing, "name" | "description">
.
有人知道这是怎么回事吗?
Does anyone knows what's going on?
推荐答案
Omit
使用 keyof
获取一个类型的所有键,然后从中排除省略键.所以 Omit
的定义可能是:
Omit
uses keyof
to get all the keys of a type and then excludes the omit keys from that. So a definition of Omit
might be:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
这种方法的问题(不是还有另一种方法)是对于带有索引签名 keyof T
的类型总是只返回 string |号码
.这是合乎逻辑的,也是唯一可能的方式.例如,Thing
的可能键是什么?好吧,它们是 id
、name
和 description
以及任何 string
,所以 keyof 可能会返回所有这些的联合<代码>id |姓名 |说明 |字符串 |号码.但是 string
是所有字符串文字类型的基本类型.这意味着 string
会吃掉所有其他字符串文字类型,从而产生 string
.
The problem with this approach (not that there is another one) is that for types with an index signature keyof T
always just return string | number
. This is logical and is the only way it could be. What are the possible keys for Thing
for example? Well they are id
, name
and description
but also any string
so keyof might return a union of all of these id | name | description | string | number
. But string
is the base type of all string literal types. This means that string
will eat up all the other string literal types resulting in string
.
鉴于 keyof Thing
是 string
排除 string
中的任何内容(使用 Exclude
) 仍然会产生 string
,给定你发现令人惊讶的签名.
Given that keyof Thing
is string
excluding anything from string
(with Exclude<keyof T, K>
) will still result in string
, given the signature you found surprising.
这篇关于在具有索引类型签名的类上使用 Omit 类型会导致不需要最少的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!