TypeScript学习笔记五:语句


语句(Statements)

  这一节讲述ts为js语句提供的静态类型检测。ts本身并没有引入任何新的语句结构,但是它扩展了本地声明的语法,如接口、类型别名和枚举声明。

5.1 块(blocks)

  块扩展了包括本地接口、类型别名和枚举声明(ECMAScript 2015 语法中已经存在类)在内的语法。

  Declaration:  ( Modified )
    …
    InterfaceDeclaration
    TypeAliasDeclaration
    EnumDeclaration

  声明:

     ...

    接口声明

    类型别名声明

    枚举声明

  本地类、接口、类型别名和枚举声明都是块作用域,与”let”和“const”声明相似。

  什么是变量语句?

  变量语句包括可选的类型注释

  VariableDeclaration:  ( Modified )
    SimpleVariableDeclaration
    DestructuringVariableDeclaration

  变量声明:

    简单变量声明

    析构变量声明

  变量语句是一个简单变量声明或者一个析构变量声明。

5.1.1 简单变量声明(Simple Variable Declaration)

  简单变量声明引入了一个命名变量和可选的初始化值。

  SimpleVariableDeclaration:
    BindingIdentifier   TypeAnnotationopt   Initializeropt

  简单变量声明:

    绑定标识符 类型注释(可选) 初始化(可选)

  简单变量声明引入了一个类型“T”,“T”由以下条件决定:

  • 如果声明包含类型注释,那么“T”就是此类型。
  • 否则,如果声明包含一个初始化表达式,那么“T”就是初始化表达式类型的宽泛格式(widened form)。
  • 否则,“T”是“Any”类型。

  当一个变量声明同时指定了一个类型注释和一个初始化表达式,初始化表达式的类型必须能够赋给给定的类型注释。

  同一声明空间中的相同变量名允许具有多个声明,允许每个声明与相同类型相关联。

  当一个变量声明具有类型注释时,此类型注释不能用“typeof”操作符来引用已声明的变量。

  下面是一些简单变量声明和它们的相关类型。

var a;                          // any
var b: number;                  // number
var c = 1;                      // number
var d = { x: 1, y: "hello" };   // { x: number; y: string; }
var e: any = "test";            // any

  下面的声明是允许的,因为变量名为“x”的所有声明的相关类型都是“Number”类型。

var x = 1;
var x: number;
if (x == 1) {
    var x = 2;
}

  以下几个变量的类型都是相同的“{ x: number; y: number; }”。

interface Point { x: number; y: number; }
var a = { x: 0, y: <number> undefined };
var b: Point = { x: 0, y: undefined };
var c = <Point> { x: 0, y: undefined };
var d: { x: number; y: number; } = { x: 0, y: undefined };
var e = <{ x: number; y: number; }> { x: 0, y: undefined };

5.1.2 析构变量声明(Destructuring Variable Declaration)

  析构变量声明引入零个或多个命名变量并对其初始化,这些初始化值来源于对象的属性或数组元素。

  DestructuringVariableDeclaration:
    BindingPattern   TypeAnnotationopt   Initializer

  析构变量声明:

    绑定模式 类型注释(可选) 初始化

  每一个指定了标识符的绑定特性或者绑定元素都引入了一个变量。变量的类型是与绑定特性或者绑定元素相关类型的宽泛格式。

  1、析构变量声明的相关类型”T”由以下条件决定:

  • 如果声明包含类型注释,那么“T”就是此类型。
  • 否则,如果声明包含一个初始化表达式,那么“T”就是初始化表达式的类型。
  • 否则,“T”是“Any”类型。

  2、绑定特性的相关类型“T”由以下条件决定:

  • 使直接包含析构变量声明、绑定特性或绑定元素的相关类型为“S”。
  • 如果“S”是“Any”类型:
    • 如果绑定特性指定了一个初始化表达式,那么“T”就是初始化表达式的类型。
    • 否则,“T”是“Any”类型。
  • 使“P”为绑定特性的名称。
  • 如果“S”具有名为“P”的显性特性,那么“T”就是此特性的类型。
  • 否则,如果“S”具有一个数字索引签名并且“P”是一个数字名称,那么“T”就是数字索引签名的类型。
  • 否则,如果“S”具有一个字符串索引签名,那么“T”就是字符串索引签名的类型。
  • 否则,绑定特性不与任何类型相关联,此时报错。

  3、绑定元素的相关类型“T”由以下条件决定:

  • 使直接包含析构变量声明、绑定特性或绑定元素的相关类型为“S”。
  • 如果“S”是“Any”类型:
    • 如果绑定元素指定了一个初始化表达式,那么“T”就是初始化表达式的类型。
    • 否则,“T”是“Any”类型。
  • 如果“S”不是一个类数组类型,那么绑定特性不与任何类型相关联,此时报错。
  • 如果绑定元素是一个可变元素,“T"是一个具有元素类型”E“的数组类型,”E"是数字索引签名”S"的类型。
  • 否则,如果“S”是一个类元组类型:
    • 数组绑定模式中绑定元素的索引是基于零的,使此索引为”N"。
    • 如果“S”具有一个数字名为“N"的特性,那么”T"就是特性的类型。
    • 否则,绑定元素不与任何类型相关联,此时报错。
  • 否则,如果“S”具有一个数字索引签名,那么“T”就是数字索引签名的类型。
  • 否则,绑定特性不与任何类型相关联,此时报错。

  当一个析构变量声明、绑定特性或变量元素指定了一个初始化表达式时,此初始化表达式的类型必须能够赋给相关类型的宽泛形式。

  当输出目标是 ECMAScript 2015或更高时,除非移除可选类型注释,析构变量声明在生成的js代码中保持不变。

  当输出目标是 ECMAScript 3或5时,析构变量声明被重写为简单变量声明。例如,以下形式的对象析构声明:

var { x, p: y, q: z = false } = getSomeObject();

  被重写为简单变量声明,如下所示:

var _a = getSomeObject(),
    x = _a.x,
    y = _a.p,
    _b = _a.q,
    z = _b === void 0 ? false : _b;

  变量“_a”和“_b”确保赋值表达式只计算一次,“void 0"表达式指代了js值”undefined"。

  同样地、一个如下格式的数组析构声明

var [x, y, z = 10] = getSomeArray();

  被重写为简单变量声明,如下所示:

var _a = getSomeArray(),
    x = _a[0],
    y = _a[1],
    _b = _a[2],
    z = _b === void 0 ? 10 : _b;

  我们将两种格式的析构声明组合起来

var { x, p: [y, z = 10] = getSomeArray() } = getSomeObject();

  它被重写为:

var _a = getSomeObject(),
    x = _a.x,
    _b = _a.p,
    _c = _b === void 0 ? getSomeArray() : _b,
    y = _c[0],
    _d = _c[1],
    z = _d === void 0 ? 10 : _d;

5.1.3 隐式类型(Implied Type)

  一个变量,参数,绑定特性或绑定元素声明指定了一个具有隐式类型的绑定模式,这种隐式类型由以下条件决定:

  • 如果声明指定了一个对象绑定模式,那么隐式类型就是一个对象类型,这个对象类型包含了相对于声明的特性集合。当它的绑定特性声明指定了一个初始化表达式时,特性是可选的。
  • 如果声明指定了一个无可变元素的数组绑定模式,那么此隐含类型就是具有相关元素的元组类型。
  • 如果声明指定了一个可变元素的数组绑定模式,那么此隐含类型就是一个数组类型,此数组包含"Any“类型的元素。

  绑定特性或者绑定元素声明的隐含类型是:

  • 声明的初始化表达式的类型,否则
  • 声明中指定的绑定模式的隐含类型,否则
  • ”Any“类型。

  下例中:

function f({ a, b = "hello", c = 1 }) { ... }

  函数参数的绑定模式的隐含类型是”{ a: any; b?: string; c?: number; }“。

 下例中:

var [a, b, c] = [1, "hello", true];

  数组的初始化表达式的类型是绑定模式的隐含类型上下文决定的。因为上下文类型是一个元组类型“[any, any, any]”,结果类型是元组类型“[number, string, boolean]",所以析构声明为”a","b"和“c"相应地赋予了"number","string"和“boolean"类型。

5.2 常量声明(Let and Const Declarations)

  Let和Const声明包含可选的类型注释。

  LexicalBinding:  ( Modified )
    SimpleLexicalBinding
    DestructuringLexicalBinding

  SimpleLexicalBinding:
    BindingIdentifier   TypeAnnotationopt   Initializeropt

  DestructuringLexicalBinding:
    BindingPattern   TypeAnnotationopt   Initializeropt

  词法绑定:

    简单词法绑定

    析构词法绑定

  简单词法绑定:

    绑定标识符 类型注释(可选) 初始化(可选)

  析构词法绑定:

    绑定模式 类型注释(可选) 初始化(可选)

5.3 If,Do和While语句

  if,do和while表达式可以是任何类型,而不仅仅是布尔类型。

5.4 For语句

  for语句中的变量声明与变量语句中的变量声明类似。

5.5 For-In语句

  在下面格式的for-in语句当中:

for (v in expr) statement

  “v”必须是作为“Any”或“String”原始类型引用的表达式。“expr”必须是“Any”类型,对象类型(Object)或者类型参数(type parameter)类型。

  在下面格式的“for-in”语句当中:

for (var v in expr) statement 

  “v”必须是一个无类型注释的变量声明,它声明了一个“Any”类型的变量。“expr”必须是“Any”,对象类型(Object)或者类型参数(type parameter)类型。

5.6 For-Of语句

5.7 Continue语句

  continue语句必须直接或间接地嵌套在循环(do、while、for或for-in)语句中。当continue语句包含一个目标标签时,此标签必须出现在一个封闭的(但不能越过函数界限)循环语句的标签组中。

5.8 Break语句

  break语句必须直接或间接地嵌套在循环(do、while、for或for-in)或者switch语句中。当break语句包含一个目标标签时,此标签必须出现在一个封闭(但不能越过函数界限)语句的标签组中。

5.9 Return语句

  return语句必须包含在函数体内,即return语句不允许存在于命名空间体或全局层中。

  无表达式的return语句返回值是“underfined”,它能存在于任何函数体中。

  当一个表达式包含return语句,如果函数具有返回类型注释,那么返回表达式类型由返回类型上下文决定,此类型必须能够赋给返回类型。否则,如果函数由一个类型“T”上下文决定,那么表达式就由“T”的返回类型上下文决定。

  在一个没有返回类型注释的函数实现中,返回类型由return语句推断而得。

  下例中:

function f(): (x: string) => number {
    return s => s.length;
}

  return语句中的lambda 表达式的类型是有”f“函数的返回类型上下文决定的。

5.10 With语句

5.11 Swith语句

  switch语句中的每一个case表达式类型必须与switch表达式类型相匹配。

5.12 Throw语句

  throw语句中的表达式可以是任何类型的。

5.13 Try语句

  try语句的catch子句引入的变量通常是任何类型的。catch子句不能包含类型注释。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM