简体   繁体   English

定义特定类型的通用打字稿排序功能

[英]Define generic typescript sort function of a certain type

I have a bunch of objects that all have a property with the type of Moment but different names for the key. 我有一堆对象,所有对象都具有Moment类型的属性,但是键的名称不同。

I'm trying to write a small utility function using typescript where I can sort any of these objects. 我正在尝试使用typescript编写一个小的实用函数,在其中可以对任何这些对象进行排序。 Could use some shoving in the right direction. 可以在正确的方向使用一些推子。

interface ExampleType1 {
    startDate: Moment;
    // ... other members
}

interface ExampleType2 {
    dueDate: Moment;
    // ... other members
}

interface ExampleType3 {
    createdAt: Moment;
}

I would expect my function look something like this (half pseudocode): 我希望我的函数看起来像这样(半伪代码):

function sortByDateAsc(data: ATypeThatHasAMoment[], keyName: KeyToTheMomentTypeWithinATypeThatHasAMoment) {
    return data.sort((a, b) => {
        // whatever sort logic i use here
        // accessing the Moment object via a[keyName] and b[keyName]
    }
}

I've been fiddling with something like this 我一直在摆弄这样的东西

function sortByDateAsc<T, K extends keyof T>(data: T[], dateKey: K);

Though within the function T[K] doesn't have a type? 尽管函数T [K]中没有类型? I'm not sure how to tell the function "T[K] has to be of type Moment" 我不确定如何告诉函数“ T [K]必须为Moment类型”

You could do it this way: 您可以这样进行:

declare function sortByDateAsc<K extends keyof any, T extends Record<K, Moment>>(
  data: T[], 
  dateKey: K
): T[];

where you are constraining T to be a type where T[K] is Moment . 其中将T约束为T[K]Moment This has the benefit of being simple to define and it works... but it might not give nice IntelliSense hints though. 这具有易于定义的优点,并且可以工作……但是,它可能不会给出很好的IntelliSense提示。 For example: 例如:

declare const ex1arr: ExampleType1[];
sortByDateAsc(ex1arr, "startdate"); // error
//            ~~~~~~ <-- "startdate" not in ExampleType1

This is given as an error on ex1arr , not an error on "startdate" . 这是作为ex1arr上的错误ex1arr ,而不是"startdate"上的错误给出的。 Moreover it does not suggest "startDate" as a correction. 此外,它不建议将"startDate"作为更正。


Instead you can use a more complicated conditional type like this: 相反,您可以使用更复杂的条件类型,如下所示:

type KeysMatching<T, V> = {[K in keyof T]: T[K] extends V ? K : never}[keyof T];
declare function sortByDateAsc<T extends any, K extends KeysMatching<T, Moment>>(
  data: T[], 
  dateKey: K
): T[];

Instead of constraining T , that signature constrains K to be the keys where T[K] matches Moment . 代替约束T ,该签名将K约束为T[K]匹配Moment的密钥。 Now the same example gives you a better error: 现在,同一示例为您提供了更好的错误:

declare const ex1arr: ExampleType1[];
sortByDateAsc(ex1arr, "startdate"); // error
//                    ~~~~~~~~~~~ <-- does not match "startDate"

with better IntelliSense hints when you start typing the dateKey parameter (it suggests "startDate" ). 当您开始键入dateKey参数时,它具有更好的IntelliSense提示(建议使用"startDate" )。


Either way should work. 两种方法都应该起作用。 Hope that helps. 希望能有所帮助。 Good luck! 祝好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM