强制 TypeScript 中要排序的属性类型。

huangapple go评论57阅读模式
英文:

Enforce type of property to sort by in typescript

问题

我想按TypeScript中的数值属性对对象数组进行排序。

为了实现这一目标,我有以下代码。这个代码的问题在于它不强制要求T类型的prop键下的值必须是数字。当然,我可以在运行时检查arr中的任何值的类型,但我想知道如何通过TypeScript在编译时强制执行这一要求。

function sortByProperty<T>(arr: T[], prop: keyof T): T[] {
    return arr.sort((a, b) => a[prop] - b[prop]);
}
英文:

I want to sort an array of objects by a numeric property in typerscript.

To do this, I've got the below code. This has the problem that it doesn't enforce that the value at the prop key of T need be numeric. Of course I could just check this at runtime with checking the type of any of the values in arr, but I would like to know how to enforce this at compile time through the use of typescript.

function sortByProperty&lt;T&gt;(arr : T[], prop : keyof T) : T[] {
    return arr.sort((a, b) =&gt; a[prop] - b[prop]);
}

答案1

得分: 1

以下是代码部分的中文翻译:

function sortByProperty<T extends Record<K, number>, K extends PropertyKey>(
  arr: T[],
  prop: K & keyof T
): T[] {
  return arr.sort((a, b) => a[prop] - b[prop]);
}

我们将prop的类型存储在一个新的泛型类型K中,并强制要求T必须是一个对象类型,其中属性K的类型是number

这会导致在选择不对应number属性的属性名称时产生编译时错误。

// 有效
sortByProperty([{
    a: "",
    b: "",
    c: 0
}], "c")

// 错误:类型'string'不能赋值给类型'number'
sortByProperty([{
    a: "",
    b: "",
    c: 0
}], "a")

Playground

英文:

A simple solution would look like this:

function sortByProperty&lt;T extends Record&lt;K, number&gt;, K extends PropertyKey&gt;(
  arr: T[],
  prop: K &amp; keyof T
): T[] {
  return arr.sort((a, b) =&gt; a[prop] - b[prop]);
}

We store the type of prop in a new generic type K and enforce that T must be an object type where the type of the property K is number.

This leads to a compile time error, if we choose a property name which does not correspond to a number property.

// valid
sortByProperty([{
    a: &quot;&quot;,
    b: &quot;&quot;,
    c: 0
}], &quot;c&quot;)

// Error: Type &#39;string&#39; is not assignable to type &#39;number&#39;
sortByProperty([{
    a: &quot;&quot;,
    b: &quot;&quot;,
    c: 0
}], &quot;a&quot;)

Playground

huangapple
  • 本文由 发表于 2023年2月6日 17:36:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75359542.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定