在具有索引类型签名的类上使用 Omit 类型会导致不需要最少的属性 [英] Using Omit type on classes with a index type signature results in minimum properties not being required

查看:17
本文介绍了在具有索引类型签名的类上使用 Omit 类型会导致不需要最少的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,它具有一些必需的属性,然后可以具有由扩展该属性的类定义的其他属性(或者无论如何,一些我不知道的额外属性).

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 的可能键是什么?好吧,它们是 idnamedescription 以及任何 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 Thingstring 排除 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆