TypeScript入门

TypeScript入门

搭建开发环境
安装TypeScript编译器 npm install -g typescript

一. 字符串新特性
... 的特性
1.多行字符串,这个将保存换行,空格

  // index.ts
  var content = `aaa
  bbb
  ccc
  `
  // index.js
  var content = "aaa\nbbb\nccc";

2.字符串模板
index.ts

var myname = "xxx";
var getName = function () {
  return "yyy";
}
console.log(`Hi ${myname}`);
console.log(`Hi ${getName()}`)

index.js

var myname = "xxx"
var getName = function () {
  return "yyy";
}
console.log("Hi" + myname);
console.log("Hi" + getName());

3.自动拆分字符串
inedx.ts

function test(template, name, age) {
  console.log(template);  // ["hello my name is ", ", I am ", ""]
  console.log(name);      // xxx
  console.log(age);       // 18
}

var myname = "xxx"

var getAge = function () {
  return 18;
} 

test`hello my name is ${myname}, I am ${getAge()}`

index.js

var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
  if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
  return cooked;
};
function test(template, name, age) {
  console.log(template);
  console.log(name);
  console.log(age);
}
var myname = "xxx";
var getAge = function () {
  return 18;
};
test(__makeTemplateObject(["hello my name is ", ", I am ", ""], ["hello my name is ", ", I am ", ""]), myname, getAge());

二. 参数新特性
1. 参数类型
变量, 方法, 方法参数后面使用冒号 : 指定参数的类型
基本类型: string number boolean any void(方法的返回值) 自定义类型

   // index.ts
   var myname: string = "xxx";
   myname = 13;
   // 
   var myname = "xxx";
   myname = 13;

注意:

  1. 这段代码只会在.ts文件中报错, 因为js没有类型检查
  2. ts参数没有冒号就会在第一次赋值的时候,确定类型
  3. 如果想赋值任何类型需要加 : any

自定义类型:

  class Person {
    name: string;
    age: number;
  }
  var zhangsan: Person = new Person()
  zhangsan.name = "zhangsan"
  zhangsan.age = 12

2. 参数默认值

在参数声明后面用等号来指定参数的默认值

  // index.ts
  function test(a: string, b: string, c: string = "dudu") {
    console.log(a);
    console.log(b);
    console.log(c);
  }

  test("xxx", "yyy", "zzz");
  test("xxx", "yyy");

注意: 带默认值的参数, 一定要声明在最后面

3. 可选参数
在方法的参数声明后面用问号来标注此参数为可选参数

  // index.ts
  function test(a: string, b?: string, c: string = "dudu") {
    console.log(a); // xxx
    console.log(b); //
    console.log(c); // dudu
  }

  test("xxx");

注意: 可选参数必须在必选参数的后面

三. 操作符
1. Rest和Spread 操作符

... 可以向内传入任意个参数

  // index.ts
    function fun(...args) {
      args.forEach(function (arg) {
          console.log(arg)
      });
    }

    fun(1, 2, 3);
    fun(4, 5, 6, 7, 8); 

    // index.jsfunction fun() {
    var args = [];
      for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
      }
      args.forEach(function (arg) {
          console.log(arg);
      });
    }
    fun(1, 2, 3);
    fun(4, 5, 6, 7, 8);

... 还可以表示传入固定个参数

  // index.ts
  function fun(a, b, c) {
    console.log(a);
    console.log(b);
    console.log(c);
  }

  var args = [1, 2]
  fun(...args);
  var arg = [1, 2, 3, 4, 5, 6]
  fun(...arg)

  // index.js
  function fun(a, b, c) {
    console.log(a);
    console.log(b);
    console.log(c);
  }
  var args = [1, 2];
  fun.apply(void 0, args);
  var arg = [1, 2, 3, 4, 5, 6];
  fun.apply(void 0, arg);

注意: 这种写法在ts中报错, 但js中可以实现效果

3. generator函数

关键字 yield 控制函数的执行过程, 手工暂停恢复代码执行

  // index.ts
  function* doSome() {
    console.log("start");
    yield;
    console.log("finish")
  }

  var func = doSome();
  func.next(); // start
  func.next(); // finish

相当于打了一个断点, 在第一次调用next()方法时,到yield暂停,再调用一次next()才会向下执行

index.js

  var __generator = (this && this.__generator) || function (thisArg, body) {
      var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
      return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
      function verb(n) { return function (v) { return step([n, v]); }; }
      function step(op) {
          if (f) throw new TypeError("Generator is already executing.");
          while (_) try {
              if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
              if (y = 0, t) op = [op[0] & 2, t.value];
              switch (op[0]) {
                  case 0: case 1: t = op; break;
                  case 4: _.label++; return { value: op[1], done: false };
                  case 5: _.label++; y = op[1]; op = [0]; continue;
                  case 7: op = _.ops.pop(); _.trys.pop(); continue;
                  default:
                      if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                      if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                      if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                      if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                      if (t[2]) _.ops.pop();
                      _.trys.pop(); continue;
              }
              op = body.call(thisArg, _);
          } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
          if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
      }
  };
  function doSome() {
      return __generator(this, function (_a) {
          switch (_a.label) {
              case 0:
                  console.log("start");
                  return [4 /*yield*/];
              case 1:
                  _a.sent();
                  console.log("finish");
                  return [2 /*return*/];
          }
      });
  }
  var func = doSome();
  func.next();
  func.next();

my.ts

  function* getStockPrice(stock) {
      while (true) {
          // 返回一个0~100的数字
          yield Math.random() * 100;
      }
  }

  var priceGenerator = getStockPrice("CBM");

  var limitPrice = 15; // 低于这个价格才会买
  var price = 100;  // 起始价格

  while (price > limitPrice) {
      // 调用函数, 返回数字, while继续判断
      price = priceGenerator.next().value
      console.log(`The generator return ${price}`)
  }
  console.log(`Buying at ${price}`)

my.js

  var __generator = (this && this.__generator) || function (thisArg, body) {
      var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
      return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
      function verb(n) { return function (v) { return step([n, v]); }; }
      function step(op) {
          if (f) throw new TypeError("Generator is already executing.");
          while (_) try {
              if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
              if (y = 0, t) op = [op[0] & 2, t.value];
              switch (op[0]) {
                  case 0: case 1: t = op; break;
                  case 4: _.label++; return { value: op[1], done: false };
                  case 5: _.label++; y = op[1]; op = [0]; continue;
                  case 7: op = _.ops.pop(); _.trys.pop(); continue;
                  default:
                      if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                      if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                      if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                      if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                      if (t[2]) _.ops.pop();
                      _.trys.pop(); continue;
              }
              op = body.call(thisArg, _);
          } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
          if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
      }
  };
  function getStockPrice(stock) {
      return __generator(this, function (_a) {
          switch (_a.label) {
              case 0:
                  if (!true) return [3 /*break*/, 2];
                  // 返回一个0~100的数字
                  return [4 /*yield*/, Math.random() * 100];
              case 1:
                  // 返回一个0~100的数字
                  _a.sent();
                  return [3 /*break*/, 0];
              case 2: return [2 /*return*/];
          }
      });
  }
  var priceGenerator = getStockPrice("CBM");
  var limitPrice = 15; // 低于这个价格才会买
  var price = 100; // 起始价格
  while (price > limitPrice) {
      // 调用函数, 返回数字, while继续判断
      price = priceGenerator.next().value;
      console.log("The generator return " + price);
  }
  console.log("Buying at " + price);

4. destructuring解构表达式

通过表达式将对象数组拆解成任意数量的变量

从对象中拆解

index.ts

  function getStock() {
      return {
          code: "CBA",
          price: {
            price1: 99,
            price2: 100
          },
          aaa: "dud"
      }
  }
  // code: c 起别名  
  var {code: c, price: {price1} } = getStock();
  console.log(c); // CBA
  console.log(price) // 100

index.js

  function getStock() {
      return {
          code: "CBA",
          price: 99
      };
  }
  var _a = getStock(), code = _a.code, price = _a.price;

从数组中拆解
my.ts

  var array = [1, 2, 3, 4]
  var [number1, number2, ...others] = array
  function doSome([number1, number2, ...others]) {
      console.log(number1); // 1
      console.log(number2); // 2
      console.log(others);  // [3, 4]
  }

  doSome(array);

my.js

  var array = [1, 2, 3, 4];
  var number1 = array[0], number2 = array[1], others = array.slice(2);
  function doSome(_a) {
      var number1 = _a[0], number2 = _a[1], others = _a.slice(2);
      console.log(number1);
      console.log(number2);
      console.log(others);
  }
  doSome(array);

四. 表达式和循环

1.箭头表达式

用来声明匿名函数, 消除传统匿名函数的this指针问题

index.ts

  var myArray = [1, 2, 3, 4, 5];
  console.log(myArray.filter(value => value % 2 == 0));
  // index.js
  var myArray = [1, 2, 3, 4, 5];
  console.log(myArray.filter(function (value) { return value % 2 == 0; }));

注意: 方法只有一行可以省略括号return, 参数只有一个可以省略括号

2.for in, for of

  // for in
  var myArray = [1, 2, 3, 4];
  myArray.desc = "four number";
  for (var i in myArray) {
      console.log(i); // 1 2 3 4 desc
  }

  // for of
  var myArray = [1, 2, 3, 4];
  myArray.desc = "four number";
  for (var i of myArray) {
      if (n > 2) break;
      console.log(i); // 1 2
  }

for of循环可以被打断, for in不可以, for of当参数为一个字符串时, 会将每一个字符打印出来

五. 类(class)

TypeScript的核心, 使用TypeScript开发时, 大部分代码都是写在类里的

1.定义: 用class关键字和类名声明的

  // index.ts
  class Person {
  name;
  // 在用关键字new这个类的时候才会被调用一次, 不可以访问
  constructor(name: string) { // 构造函数
      console.log("haha")
      this.name = name; // 表示声明时,必须初始化name
  }
  // 构造函数上没有默认控制符
  // constructor(public name: string) { } 简化
  age;
  // pubic 访问控制符(默认) 内外都可以访问 
  // private 只有在类的内部才可以访问到
  // protected 受保护的 可以在类的内部和类的子类被访问到
  eat() {
      console.log(this.name);
      }
  }

  // extends 声明继承关系   继承类的所有属性和方法
  class Emp extends Person{
      constructor(name: string, code: string) {
          // 子类的构造函数一定要调用父类的构造函数
          super(name); // super 调用父类的构造函数
          this.code = code
      }
      code: string;
      work() {
          super.eat() // super还可以调用父类的方法
          this.doWork()
      }
      private doWork() { // 私有方法
          console.log("work")
      }
  }
  var e1 = new Emp("jing", "zhang");

  var p1 = new Person("du");
  p1.age = 19;
  p1.eat();

  var p2 = new Person("liu");
  p2.age = 22;
  p2.eat();

2.泛型 (generic)

参数化的类型, 一般用来限制集合的内容

  // index.ts
  // 指定数组只能用来放某一种类型的元素, 不能放其他类型的元素
  var workers: Array<Person> = [];
  workers[0] = new Person("zhang");
  workers[1] = new Emp("liu", "du");
  workers[2] = 2; // 报错

3. 接口 (Interface)

用来建立某种代码约定, 使得其他开发者在调用某个方法创建新的类时必须遵循接口所定义的代码约定

①. 作为一个方法的参数的类型声明

    interface IPerson {
        name: string;
        age: number;

    }
    class Person {

        constructor(public config: IPerson) {} // 作为一个方法的参数的类型声明
    }
    var p1 = new Person({
        name: "zhangsan",
        age: 11
    })

② 所有声明实现这个接口的类必须实现这个方法

    interface Animal {
        eat();
    }

    class Sheep implements Animal { // 所有声明实现这个接口的类必须实现这个方法
        eat() {
            console.log("I eat buf")
        }
    }

六. 模块 (Module)

模块可以帮助开发者将代码分割为可重用的单元.开发者可以自己决定将模块中的哪些资源(类, 方法,变量)暴露出去供外部使用,哪些资源只在内部使用

export 导出 import 导入

  //a.ts
  export var prop;
  var prop1;
  export function func() {}
  function fun2 () {}
  export class Clazz() {}
  class Clazz() {}

  //b.ts
  import {prop1, func, Clazz} from  "./a"
  console.log(prop1);
  func();
  new Clazz();
  export function func3 () {}

②注解 (annotation)

注解为程序的元素(类, 方法, 变量)加上更直观明了的说明, 这些说明信息与程序的业务逻辑无关, 而是提供指定的工具或框架使用的
告诉一个框架如何处理一个类,如Angle

③类型定义文件 (*.d.ts)

类型定义文件用来帮助开发者在TypeScript中使用已有的JavaScript的工具包, 如: jQuery

.d.ts结尾的文件 可以到GitHub的DEfinitelyTyped 里面有绝大部分的JS工具包

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值