Typescript 是否真正遵循泛型中参数化类型(T、U、V、W)的命名惯例?

4

我不确定在TS中我们是否遵循C++/Java或许多其他语言(T,U,V,W)的参数化类型命名约定。

我在TS中看到了许多次参数化类型约定的混合使用。例如,在TS 2.8的发布说明中:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

为什么选择R而不是U
接下来是另一个例子:
type Unpacked<T> = T extends (infer U)[]
  ? U
  : T extends (...args: any[]) => infer U
  ? U
  : T extends Promise<infer U>
  ? U
  : T;

为什么用 U 而不是 R
另一个例子,在上面的代码块中:
type T0 = Unpacked<string>; // string
type T1 = Unpacked<string[]>; // string
type T2 = Unpacked<() => string>; // string
type T3 = Unpacked<Promise<string>>; // string
type T4 = Unpacked<Promise<string>[]>; // Promise<string>
type T5 = Unpacked<Unpacked<Promise<string>[]>>; // string

但在TS源代码中:

// We represent tuple types as type references to synthesized generic interface types created by
// this function. The types are of the form:
//
//   interface Tuple<T0, T1, T2, ...> extends Array<T0 | T1 | T2 | ...> { 0: T0, 1: T1, 2: T2, ... }

以上的问题只是举例说明,你不需要回答它们。 我可以添加其他一些示例,其中U有时被视为返回类型,有时只是第二种类型。
我真正的问题是:我们是否(真正地)遵循Java Generic Types convention来使用TS Generics? 如果不是,TS使用了哪些约定来处理泛型? 除了类型名称的 PascalCase 和类型属性/方法的 camelCase 之外,TS还存在多少种不同的类型约定?

1
我真的不太明白这些示例与您链接的Java约定在任何实质性方面有什么区别:使用少量大写字符,其中一些常见名称对应于它们所代表的第一个字母(例如K表示键,P表示属性,R表示返回等),或者一些相关类型的序列,如TUVABC。虽然我不确定您的问题是否有明确的答案...但是这样的约定有点像有机/众包的,而不是从高处颁布的。 - jcalz
非常感谢您的评论。 因此,我们可以得出结论,只要我保持(有时)描述性的(有时)随机大写字母单词,我就遵循Typescript约定? 这与我提供的Java约定并不完全相同。 例如,在Java中,我必须使用TUV来符合多类型泛型的类型参数命名约定。在TS中,我可以随机和可互换地使用TUVABCXYZT0T1T2。 因此,我认为可以安全地说,这可能起源于C++ / Java,但它不那么严格。 - GBra 4.669
1
链接的文档中说:“最常用的类型参数名称是...”,而不是“唯一可接受的类型参数名称是...”。这是一个示例列表,因此是描述性的而不是规定性的。很抱歉,我真的看不出任何东西“更不严格”或“更严格”。 - jcalz
这个问题除了个人意见以外,还有其他可能的答案吗?我试图找出一个规范的答案。在 GitHub 上有一些问题,比如 ms/TS#878ms/TS#6168,TS 设计团队表示“我们不打算强加任何这样的约定”,因此从这个意义上讲,答案是“在 TS 中没有规范的约定”。似乎 ESLint 或 TSLint 也没有推荐的类型参数设置。 - jcalz
由于Java doc链接(在我看来)似乎建议单字符大写类型与示例一起使用,而不是特别规定或建议任何内容,因此并不清楚有多少需要遵守的规则。在我的经验和观点中,如果没有歧义,TS泛型类型参数应该是大写字母,可能会更长(两个字符?一个短词?),以消除歧义。但这只是我的观点和未经证实的“经验”,所以我不会将其作为答案。我认为这可能是一个意见问题,但也可能我误解了它。 - jcalz
1
我同意你的所有观点。我尽量让它不基于个人观点(甚至不想添加像是更具描述性的命名规范这样的东西)。但我们已经接近一个基于个人观点的答案了。我认为你的评论可能是我的问题的一个非常好的答案,对其他人也可能有用。由你决定,你有更多的SO经验,我们可以投票关闭这个问题,或者你可以将你的评论复制为答案。如果你投票关闭,我也会这样做。非常感谢。 - GBra 4.669
1个回答

3

(来自评论,大多数)

最接近我能想象的回答这个问题的方式,而不仅仅是我的意见,是指向一些描述“TypeScript类型参数命名约定”的文档,并将其与您链接的Java泛型教程文档进行比较。

如果是这样,TypeScript设计团队的官方立场似乎是“我们不打算强加任何这样的惯例给其他人”,或者“在TS中没有规范的命名惯例”。请参见microsoft/TypeScript#6168microsoft/TypeScript#878,特别是this comment

总的来说,我们对于为人们决定样式方面并不感兴趣。说有一个TS的One Approved Style会违背我们的理念,即我们在这里提供JS类型,无论你如何编写它(当然,在合理的范围内)。

还有ESLint的naming-convention规则TSLint的naming-convention规则,这些规则可以在受代码检查的代码库中强制执行类型参数命名约定,但似乎默认情况下不会这样做。因此,似乎没有官方约定足够正式,可以默认强制执行。


为了比较,让我们看一下你提供的 Java 泛型教程文档中相关部分:
类型参数命名约定
按照惯例,类型参数名称是单个大写字母。这与您已经了解的变量命名约定形成了鲜明对比,并且有很好的原因:如果没有这个约定,将很难区分类型变量和普通类或接口名称。
最常用的类型参数名称包括:
- E - Element(Java 集合框架广泛使用) - K - Key - N - Number - T - Type - V - Value - S、U、V 等 - 第二、第三、第四类型
在 Java SE API 和本课程的其余部分中,您将看到这些名称的使用。
请注意,上面列出的枚举列表被描述为“最常用的类型参数名称”,而不是“唯一允许的类型参数名称”;它是一个示例列表,因此是描述性的而不是规定性的。
关于选择“单个大写字母”的部分更像是一种规定:大写字母往往能够区分类型名称和变量名称,而单个字符的类型名称则倾向于区分类型参数和特定类型(如类或接口)。但我有同样的感觉,这不是来自上级的命令,而是对普遍实践的观察。

因此,我们可以假设停在那里并说:“在TypeScript或Java中没有官方或规范的类型参数命名约定,任何非正式的这样的约定都是主观看法。”

但为了列出我认为TypeScript中非官方约定实际上是什么,我会继续。请记住,这是我的观点,人们可以合理地持不同意见。


我认为上面列出的Java命名约定与TypeScript泛型类型参数的事实约定相当吻合:使用单个大写字母,对应于它们所代表的内容的第一个字母,例如:
  • T表示“类型”,是最常用的类型参数名称;
  • K表示“键”,或者P表示“属性”,两者通常受到PropertyKeykeyof Tkeyof SomeInterfacekeyof SomeClass的限制;
  • V表示“值”,通常与“键”K一起使用;
  • A表示“参数”,R表示“返回”,分别对应于函数签名的剩余参数列表和返回类型,如(...args: A) => R
  • N表示“数字”,S表示“字符串”,B表示“布尔”,用于受原始类型限制的类型参数;

或一些相关类型的序列。

  • TUVW等,以T作为“类型”的开头,然后按字母顺序递增,当需要更多类型时,要注意只能通过这种方式获得一些类型;
  • ABCD等,从字母表的开头开始,当您希望使用大量类型参数且尚未为其他内容使用类型参数时。

这些约定并非绝对,必要时可能会被扭曲以避免歧义或其他混淆。如果您需要的类型参数比上述方法能够提供的更多,并且存在名称冲突,则可能希望向名称添加字符:

  • T0T1T2T3等,附加数字以获得相关类型序列;
  • KTKUKV:在TUV前缀K,表示“键的”。

我认为这种方式与传统有所不同,但仍然常见。使用短的UpperCamelCase名称更能描述类型的含义,缺点是它们可能会被误解为特定类型而不是类型参数:

  • KeyValPropArgRetTypeThis

以下方式不太常见(请记住,这只是我的个人意见!),除非有压倒性的原因需要这样做,否则应避免使用:

  • 长得像接口或类名的长名称,如InputTypeProperties
  • 在较长的类型名称前加上大写字母T,如TNotRecommended
  • 以小写字母开头的名称,如tumyType

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接