我需要创建一个通用函数,该函数将循环访问TOrderBy对象的属性(key, value),并控制台记录value对象的属性(ordinality);

type Entries<T> = {
  [K in keyof T]: [K, T[K]];
}[keyof T][];

interface ISortableItem {
  ordinality: number;
}

class SortClass {
  name: ISortableItem;
  population: ISortableItem;
}

function sortObject<TSort>(obj: TSort) {
  const objects = Object.entries(obj) as Entries<TSort>;

  for (const [key, value] of objects) {
    console.log(value.ordinality);
  }
}

当然,Typescript编译器在value.ordinality上给出了错误.

是否可以对TSort设置约束,以便其所有属性都应该实现ISortableItem

推荐答案

是的,您可以将TSort类型参数constrainRecord<keyof TSort, ISortableItem>(使用Record<K, V>表示"在类型K的键处具有类型V属性的对象"):

function sortObject<
  TSort extends Record<keyof TSort, ISortableItem>
>(obj: TSort) {
  const objects = Object.entries(obj) as Entries<TSort>;

  for (const [key, value] of objects) {
    console.log(value.ordinality); // okay
  }
}
sortObject(new SortClass()) // okay

这是一个循环约束(取决于TSort).


它在概念上类似于约束为index signature(例如{[k: string]: ISortableItem}),但接口和类实例没有得到implicit index signatures(参见microsoft/TypeScript#15300),因此使用SortClass最终会出现错误:

function sortObjectIdxSig<
  TSort extends { [k: string]: ISortableItem }
>(obj: TSort) { 
  const objects = Object.entries(obj) as Entries<TSort>;

  for (const [key, value] of objects) {
    console.log(value.ordinality); // still okay
  }
}

sortObjectIdxSig(new SortClass()) // error
// Index signature for type 'string' is missing in type 'SortClass'

Playground link to code

Typescript相关问答推荐

类型脚本如何将嵌套的通用类型展开为父通用类型

TypScript如何在 struct 上定义基元类型?

TypScript手册中的never[]参数类型是什么意思?

泛型和数组:为什么我最终使用了`泛型T []`而不是`泛型T []`?<><>

如何在第一次加载组件时加载ref数组

如何将联合文字类型限制为文字类型之一

Angular 错误NG0303在Angular 项目中使用app.Component.html中的NGFor

如何在另一个参数类型中获取一个参数字段的类型?

为什么T[数字]不也返回UNDEFINED?

如何避免推断空数组

如何正确调用创建的类型?

如何按属性或数字数组汇总对象数组

有没有办法在Zod中使用跨字段验证来判断其他字段,然后呈现条件

如何键入派生类的实例方法,以便它调用另一个实例方法?

使用Type脚本更新对象属性

埃斯林特警告危险使用&as";

React中的效果挂钩在依赖项更新后不会重新执行

Typescript泛型-键入对象时保持推理

基于参数的 TS 返回类型

递归地排除/省略两种类型之间的公共属性