我正在try 为泛型类型设置缺省值{ createdAt: 'asc' },它将用于在OrderByType中创建密钥.我已经try 使用Record来创建一个新类型,但结果类似.

这是我的最后一次try :

type OrderByType<T> = {
  [key in keyof Partial<T>]: 'asc' | 'desc';
};

export class OrderByArgs<Entity extends { createdAt: Date }> {
  orderBy: OrderByType<Entity> = { createdAt: 'asc' };
}

错误:

Type '{ createdAt: "asc"; }' is not assignable to type 'OrderByType<Entity>'.

我做错了什么?

推荐答案

你遇到的问题是

type OrderByType<T> = { [K in keyof Partial<T>]: 'asc' | 'desc'; };

似乎对于编译器来说,对于genericEntityconstrained{ createdAt: Date }来说,{ createdAt: 'asc' }可以赋给OrderByType<keyof Entity>的嵌套层太多了.

这类问题被报告为microsoft/TypeScript#27598,尽管它被认为可以正常工作.一般来说,编译器并不擅长知道像{createdAt: 'asc'}这样的具体类型何时可以赋值给像OrderByType<T>这样的泛型类型,除非有人显式编写了编译器代码路径来处理它.


幸运的是,我们可以重构您的代码,使其正常工作:

The Partial utility type只是使用mapping modifier将所有属性变为可选.因此,您的OrderByType<T>实际上是{[K in keyof {[P in keyof T]?: T[P]}]: 'asc' | 'desc'},它放置一个内部映射类型来添加可选修饰符,然后放置一个外部映射类型来仅保留这些修饰符.

如果您将其更改为概念上相同但更简单的实现

type OrderByType<T> = { [K in keyof T]?: 'asc' | 'desc' }

然后事情就开始运转了:

export class OrderByArgs<Entity extends { createdAt: Date }> {
  orderBy: OrderByType<Entity> = { createdAt: 'asc' }; // okay

现在对编译器来说很明显,OrderByType<T>本身肯定是一个全可选的类型,而且由于createdAt肯定是Entity的键,那么无论Entity中有多少额外的键,{createdAt: 'asc'}都肯定可以赋值给OrderByType<Entity>.

Playground link to code

Typescript相关问答推荐

具有映射返回类型的通用设置实用程序

如果我有对象的Typescript类型,如何使用其值的类型?

处理API响应中的日期对象

TypeScript Page Routing在单击时不呈现子页面(React Router v6)

对深度对象键/路径进行适当的智能感知和类型判断,作为函数参数,而不会触发递归类型限制器

泛型类型,引用其具有不同类型的属性之一

如何编写一个类型脚本函数,将一个对象映射(转换)为另一个对象并推断返回类型?

TypeScrip原始字符串没有方法

在实现自定义主题后,Angular 不会更新视图

类型脚本满足将布尔类型转换为文字.这正常吗?

AngularJS服务不会解析传入的Json响应到管道中的模型

刷新时保持当前名称的Angular

Angular material 无法显示通过API获取的数据

有没有办法防止类型交集绕过联合类型限制?

打字错误推断

如何编辑切片器以使用CRUD调用函数?

如何在打字角react 式中补齐表格组

为什么类型脚本使用接口来声明函数?他的目的是什么.

可以将JS文件放在tsconfig';s includes/files属性?或者,我如何让tsc判断TS项目中的JS文件?

Angular 16:无法覆盖;baseUrl;在tsconfig.app.json中