【发布时间】:2021-05-25 06:01:45
【问题描述】:
我不确定在 TS 中我们是否遵循 C++/Java 或许多其他语言 (T,U,V,W) 等参数化类型的命名约定。
我多次看到 TS 中参数化类型约定的混合使用。 比如在release notes of 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 对泛型遵循什么样的约定? TS 中同时存在多少种不同的类型约定(除了类型名称的明显 PascalCase 和类型属性/方法的 camelCase)?
【问题讨论】:
-
我真的看不出这些示例与您链接的 Java 约定有何有意义的不同:使用少量大写字符,一些常用名称对应于它们所代表的第一个字母(
K用于键,P用于属性,R用于返回等)或一些相关类型的序列,例如T,U,V或A,B,C.不过,我不确定您的问题是否有明确的答案......像这样的约定在某种程度上是有机的/众包的,而不是从高处颁布的。 -
非常感谢您的评论。所以我们可以得出结论,只要我保留一个(有时)描述性(有时)随机大写的单个字母,我就遵循 Typescript 约定?与我链接的 Java 约定不完全相同。例如,在 Java 中,我必须使用
T,U,V来抱怨多种类型泛型的类型参数命名约定。在 TS 中我可以使用T,U,V或A,B,C或X,Y,Z或 @987654376@,@, 987654358@随机互换。因此,我想我可以肯定地说,它可能起源于 C++/Java,但不那么严格。 -
链接的文档说“最常用的类型参数名称是……”而不是“唯一可接受的类型参数名称是……”。它是 examples 的列表,因此是描述性的而不是规定性的。抱歉,我真的看不出有什么是“不那么严格”或“更严格”的。
-
这个问题有没有可能只用意见来回答?我试图弄清楚一个规范的答案会是什么样子。有像ms/TS#878 和ms/TS#6168 这样的GitHub 问题,TS 设计团队说“我们不打算将任何此类约定强加给其他人”,因此从这个意义上说,答案是“TS 中没有规定性约定”。 ESLint 或 TSLint 似乎也没有推荐的类型参数设置。
-
我同意你的所有观点。我试图让它尽可能不基于选项(甚至不想添加诸如:更具描述性的命名约定怎么样?)。但我们正在接近基于意见的答案。我认为您的 cmets 可能是我问题的一个非常好的答案,它可能对其他人有用。取决于您,您有更多的 SO 经验,我们可以根据意见投票结束问题,或者您可以复制您的 cmets 作为答案。如果你投票支持关闭,我也会这样做。非常感谢。
标签: angular typescript generics typescript-typings