typescript - 强制 Typescript 通用参数(a : T, B: T)为相同类型

标签 typescript typescript-generics

给定:

function sorter<T extends string | number> () {
  const icf = new Intl.Collator().compare
  return (a: T, b: T) => typeof a === 'number' ? a - b : icf(a, b)
}

我们收到 Typescript 类型错误:

typescript error

我们知道,如果a是一个数字,那么b也将是一个数字,同样,如果a是一个字符串,那么 >b 也将是一个字符串。调用排序器的函数知道此信息,即仅在调用返回的函数时才知道。按照设计,我们从不期望得到异构的元素。

有哪些选项可以正确断言这些类型?

Typescript Playground

最佳答案

你可以这样做:

type T = number | string;

function numSorter(a: number, b: number){
  return a - b;
}

function stringSorter(a: string, b: string, locale: string) {
  const icf = new Intl.Collator(locale).compare;
  return icf(a,b)
}

function picker(a: T, b: T, locale: string) {
  if (typeof a === 'number' && typeof b === 'number') {
    return numSorter(a,b);
  } else if (typeof a === 'string' && typeof b === 'string') {
    return stringSorter(a,b, locale);
  } else {
    throw Error("incompatible types");
  }
}

function sorter(locale: string) {
  return (a:T, b:T) => picker(a,b,locale);
}

const mySorter = sorter("US");

console.log(mySorter(1,2)); //both numbers, so ok
console.log(mySorter("world","hello")); // both strings, so ok
console.log(mySorter(1,"hello")); // incompatible types

输出如下:

enter image description here

我可能是错的,但我认为这种方法违背了静态类型检查的目的。通用引用仍然需要有具体的实现。

在这种情况下,对于不同类型的numberstring,您执行的操作是不同的,因此不存在重叠。通用方法对于在功能上确实有一些重叠的对象可能很有用,例如它们都有一个通用方法,例如如果您想要一个辅助方法来查找数组的长度(如 docs 中所示):

function loggingIdentity<Type>(arg: Array<Type>): Array<Type> {
  console.log(arg.length); // Array has a .length, so no more error
  return arg;
}

这个通用函数适用于任何类型的任何数组,因为任何数组都具有 length 属性。

总的来说,我认为它对于这种情况没有用,我认为从一开始就有具体的实现,并在需要时调用正确的排序函数可能会更好。说实话,泛型有点让人头疼,尤其是在 TypeScript 中。

关于typescript - 强制 Typescript 通用参数(a : T, B: T)为相同类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72320085/

相关文章:

TypeScript 泛型 : infer key of key-value return type from function argument

javascript - 无法绑定(bind)到 'gridOptions',因为它不是 'ag-grid-angular' 的已知属性

typescript - 为什么 `T extends "A "` and ` S extends "A"`没有重叠?

typescript - 替换通用接口(interface)类型参数

javascript - 根据 Typescript 中输入对象的属性,使用键从函数返回对象

typescript 泛型 : map with keys of type T[K] to values of T itself (grouping T[] by own property value)

typescript - 缩小映射函数的泛型类型

javascript - RxJS 发出字符串数组,彼此相隔一秒

typescript - 如何使 TypeScript 与 SystemJS 一起工作? (.js 扩展名问题)

Angular - 获取当前激活的路由并使用不同的路由参数重新导航到同一页面