在TypeScript中使用尖括号的规则

47

在 TypeScript 中,何时、何地、如何以及为什么应该使用尖括号(即<...>)的一般规则是什么?

虽然我认为我理解了许多单个使用这些括号的情况,但我很难看到它们使用的一般模式:它们有时似乎在事物之前添加,有时在事物之后追加;有时用于泛型,有时用于特定类型;有时出现在我本来希望使用冒号语法的地方。

我想要一个简洁但详尽/通用的解释,介绍括号的含义、确切的语法、应该何时使用它们、不应该使用它们的情况等等。


你能否举几个你不理解的尖括号使用的例子?你所说的“出现在事物之后”和“期望使用冒号语法的地方”是什么意思?尖括号“出现在事物之前”可能是类型转换?带有“类型参数”的“事物之后”- 定义通用类型。 - Nozim Turakulov
@n.turakulov,关于before/after的问题,以下是直接从TypeScript规范中摘录的示例:在某些东西之前使用尖括号:var circle = <Circle> shape;,在某些东西之后使用尖括号:var x: KeyValuePair<number, string> = [10, "ten"];,仅使用尖括号(即既不在之前也不在之后):var <ClassName> = (function () {...。当我说“冒号语法”时,我的意思是有时你会看到<string>,有时你会看到... : string。感谢您提供的具体解释,但我正在寻找一组详尽(但简洁明了)的规则。 - Andrew Willems
2个回答

73

对于这样的问题,我建议阅读规范,特别是语法部分。像< something >这样的语法在其中使用。

  1. Type Parameters

    • Defined as < TypeParameterList > in section 3.6.1
    • Used with declarations and call signatures of classes, interfaces, functions and more

      function heat<T>(food: T): T { return food; }
                //^^^^^ Type parameter list
      
      class Pizza<T, E extends Cheese> { toppingA: T; toppingB: E }
               //^^^^^^^^^^^^^^^^^^^^ Type parameter list
      
  2. Type Arguments

    • Defined as < TypeArgumentList > in section 3.6.2
    • Used with references to generic types and calls to generic functions

      var pizza: Pizza<Pepperoni, Mozzarella>;
                     //^^^^^^^^^^^^^^^^^^^^^^ Type argument list
      pizza = heat<{ toppingA: Pepperoni, toppingB: Mozzarella}>(ingredients) 
                 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Type argument list
      

      Update 2018-07-01: As of version 2.9, generic type arguments can also be used in JSX elements and tagged templates.

       <MenuItem<Pizza> toppings={[Pepperoni, Mozzarella]} />
              //^^^^^^^ Type argument list
      
       const ratingHtml = escapeUserInput<string | number> `Customer ${feedback.customer.username} rated this pizza with <b>${feedback.rating}</b>/10!`
                                        //^^^^^^^^^^^^^^^^ Type argument list
      
  3. Type Assertions

  4. JSX expressions (when enabled)

    • Not documented in the spec, but should follow the the syntax of JSX, which is basically an expression like

      <JSXElementName JSXAttributes(optional)> JSXChildren(optional) </JSXElementName>
      

      or

      <JSXElementName JSXAttributes(optional) />
      

10
值得注意的是,现在类型断言的首选语法是 UnaryExpression as Type,因为前一种语法在 .tsx 文件中存在歧义。 - John Weisz
3
这正是我一直在寻找的。感谢您列出使用尖括号的用例,并指引我查看相关规范的部分,特别是语法部分。我已经开始阅读规范,但卡住了,没有注意到那个部分如何简洁地回答了我的问题。 - Andrew Willems
1
@AndrewWillems 很高兴能帮忙。请注意,我提供的规范链接指向其中的一个特定版本,以便答案中的链接不会在未来失效。然而,你应该使用最新版本 - noppa
@noppa,你知道我们在哪里可以找到TypeScript版本2的规范吗? - J86
@Ciwan 我也找不到。他们的TypeScript新功能文档很好地列出了新功能,但我希望他们很快更新文档目录 - noppa
显示剩余3条评论

2

它们用于多种语义明显不同的表达式,无法为其制定通用用例。这也取决于上下文,就像花括号一样。如您所知,成对的尖括号用于以下用途:

  • 作为类型断言的已弃用语法
  • 手动指定泛型类型参数
  • .tsx中声明元素

当不在.tsx文件中时,成对的尖括号几乎总是表示存在泛型类型参数的指示。可以将表达式系统制定如下(这可能是最接近的):

  • 当处于类型定义、类型注释、方法调用或类声明的上下文中时,尖括号表示泛型类型参数
  • 当处于TSX元素的上下文中时,尖括号表示由TSX/JSX编译器转换的元素

1
谢谢您的回复。关于您的第一句话:恕我直言,这种描述一定是可能的。我不知道您是否看到了我的问题更新。在其中,我展示了如何在4个简短的句子和2个5点列表中,相当清晰地列出JavaScript中花括号的所有语义上不同的用例。实际上,您的答案的其余部分,我相信已经(虽然还没有完全?)给了我我所需要的东西。(记录一下,我还不理解.tsx文件、React、JSX等。) - Andrew Willems

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