博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TypeScript快览
阅读量:5930 次
发布时间:2019-06-19

本文共 6940 字,大约阅读时间需要 23 分钟。

一. 数据类型

变量可以使用数据类型修饰, 限制了变量别随意赋值带来的不可预测性

let age: number = 12;let isDone: boolean = false;let myName: string = 'Tom';let unusable: void = undefined;let u: undefined = undefined;let n: null = null;复制代码

有的时候数据类型是不可预测的, 有的场景下, 也是需要可以接受任意类型的变量. 这时候就可以使用任意值

let anyThing: any = 'hello';anyThing = 3;复制代码

类型推断

  • 在声明时,给定了值, 那么变量就会被推断对应的类型.
let myFavoriteNumber = 'seven'; // let myFavoriteNumber: string = 'seven';myFavoriteNumber = 7;复制代码
  • 如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查
let something; // let something: any;something = 'seven';something = 7;something.setName('Tom');复制代码

联合类型

  • 一个类型可以同时指定多个类型
let myFavoriteNumber: string | number;myFavoriteNumber = 'seven';myFavoriteNumber = 7;复制代码

当使用联合类型时, 变量只能使用两个类型中公共的方法属性.

  • 如果是我们需要在方法中根据类型调用特定的方法时, 就需要使用断言语法. 断言只能从联合类型中选取类型
复制代码

对象类型---接口

程序开发有一个很流行的模式,就是面向接口编程. 接口抽象了结构, 真正的实现就可以提供多种多样的能力.

interface Person {    name: string; // name是确定属性, 实现接口的对象,必须失效该属性    age?: number; // age是可选属性, 也就是真正实现时,不需一定实现.    readonly id: number; // 只读属性, }let tom: Person = {    name: 'Tom',    age: 25,    id: 100, // 只能在对象赋值时设置值. };复制代码

数组的类型

let fibonacci: number[] = [1, 1, 2, 3, 5];// 报错, 数组中只允许单一类型let fibonacci2: number[] = [1, '1', 2, 3, 5];// 泛型数组let fibonacci: Array
= [1, 1, 2, 3, 5]; // 接口类型数组interface NumberArray { [index: number]: number;}let fibonacci: NumberArray = [1, 1, 2, 3, 5]; // 要求数组中存放不同类型的值let list: any[] = ['Xcat Liu', 25, { website: 'http://xcatliu.com' }];复制代码

函数的类型

  • 注意,输入多余的(或者少于要求的)参数,是不被允许的
function sum(x: number, y: number): number {    return x + y;}sum(1, 2); // 正常sum(1, 2, 3);// 多输入一个参数, 会报错复制代码
  • 使用可选参数, 可以省略参数的输入, 可选参数一定要在参数列表的尾部.
function buildName(firstName: string, lastName?: string) {    if (lastName) {        return firstName + ' ' + lastName;    } else {        return firstName;    }}let tomcat = buildName('Tom', 'Cat');let tom = buildName('Tom');	复制代码
  • 用接口定义函数的类型
interface SearchFunc {   (source: string, subString: string): boolean;}let mySearch: SearchFunc;mySearch = function(source: string, subString: string) {   return source.search(subString) !== -1;}复制代码

声明文件: declare

我们需要使用 declare 关键字来定义它的类型,帮助 TypeScript 判断我们传入的参数类型对不对:

declare var jQuery: (selector: string) => any;jQuery('#foo');复制代码

注意:

  • 通常声明文件放到一个单独的文件中管理. 例如: jQuery.d.ts

  • 用「三斜线指令」表示引用了声明文件, /// <reference path="./jQuery.d.ts" />

  • 第三方声明文件, npm install @types/jquery --save-dev

Node

Node.js 不是内置对象的一部分,如果想用 TypeScript 写 Node.js,则需要引入第三方声明文件:

npm install @types/node --save-dev复制代码

二. 进阶用法

关键字: type

类型别名

例如定义一个函数的类型, 参数类型加上返回值类型, 导致类型描述很长, 这时候就可以使用类型别名简化.

type Name = string;type NameResolver = () => string;type NameOrResolver = Name | NameResolver;function getName(n: NameOrResolver): Name {    if (typeof n === 'string') {        return n;    }    else {        return n();    }}复制代码

字符串字面量类型

作为类型时, 参数只能是约定好的内容. 类似于枚举

type EventNames = 'click' | 'scroll' | 'mousemove';function handleEvent(ele: Element, event: EventNames) {    // do something}handleEvent(document.getElementById('hello'), 'scroll');  // 没问题handleEvent(document.getElementById('world'), 'dbclick'); // 报错,event 不能为 'dbclick'复制代码

元祖

数组: 相同元素集合,

元祖: 不同元素集合

let xcatliu: [string, number];xcatliu[0] = 'Xcat Liu';xcatliu[1] = 25;xcatliu[0].slice(1);xcatliu[1].toFixed(2);// 报错, 类型不一致let k: [string, number] = [18,'Tom', 18]复制代码

注意:

  • 元素的定义时的位置是固定的. [18,'Tom', 18] 的类型就是[number, string, number]
  • 对应位置可以使用该位置类型的方法,
  • 如果在元祖中push
  • 额外元素的类型为元祖中元素的联合类型 number | string

关键字: enum

一般枚举

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};复制代码

编译后

var Days;(function (Days) {    Days[Days["Sun"] = 0] = "Sun";    Days[Days["Mon"] = 1] = "Mon";    Days[Days["Tue"] = 2] = "Tue";    Days[Days["Wed"] = 3] = "Wed";    Days[Days["Thu"] = 4] = "Thu";    Days[Days["Fri"] = 5] = "Fri";    Days[Days["Sat"] = 6] = "Sat";})(Days || (Days = {}));;复制代码
  • 它的默认值,如下每个较前一个 + 1
console.log(Days["Sun"] === 0); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days[2] === "Tue"); // trueconsole.log(Days[6] === "Sat"); // true复制代码
  • 手动赋值, 以最后面的数值递增.
enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 7); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days["Tue"] === 2); // trueconsole.log(Days["Sat"] === 6); // true复制代码

常数枚举

每一项的内容是常数, 不可计算得到.

const enum Directions {  Up,  Down,  Left,  Right}let dir: Directions = Directions.Up复制代码

编译后

var dir = 0 /* Up */;复制代码

外部枚举

// 此处必须使用const, 不然declare 定义的类型只会用于编译时的检查,编译结果中会被删除。declare const enum Directions {    Up,    Down,    Left,    Right}let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right];复制代码

编译结果:

var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];复制代码

三. 类的使用

访问修饰符

  • public : 任何地方都可以被访问, 默认的属性和方法都是publick
  • private: 只有当前类可以访问.
  • protected: 和private类似, 但可以被子类访问.

抽象类

abstract 用于定义抽象类和其中的抽象方法.

使用关键字 extends 继承抽象类

注意:

  • 抽象类不能被实例化
  • 抽象方法必须被子类实现

接口

接口可以描述一个对象属性, 同时可以对行为进行抽象

  • 使用关键字 implements 实现接口
  • 一个类可以实现多个接口
  • 接口之间可以是继承关系
interface Alarm {    alert();}interface Light {    lightOn();    lightOff();}interface FlyableAlarm extends Alarm{    fly();}class Door {}class SecurityDoor extends Door implements Alarm {    alert() {        console.log('SecurityDoor alert');    }}class Car implements Alarm, Light {    alert() {        console.log('Car alert');    }    lightOn() {        console.log('Car light on');    }    lightOff() {        console.log('Car light off');    }}class Plane implements FlyableAlarm{    alert(){        console.log('Plane alert');    }    fly(){        console.log('Plane fly');    }}复制代码
  • 接口继承类
class Point {    x: number;    y: number;}interface Point3d extends Point {    z: number;}let point3d: Point3d = {x: 1, y: 2, z: 3};复制代码

泛型

定义函数,接口或类的时候, 不预先指定具体的类型, 而在使用的时候再指定类型的一种特性

  • 函数使用泛型
function createArray
(length: N, value: T): Array
{ let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result;}createArray
(3, 'x'); // ['x', 'x', 'x']复制代码
  • 接口使用泛型
interface CreateArrayFunc {    
(length: number, value: T): Array
;}// 也可以把泛型提升到接口名上//interface CreateArrayFunc
{
// (length: number, value: T): Array
;//}let createArray: CreateArrayFunc;createArray = function
(length: number, value: T): Array
{ let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result;}createArray(3, 'x'); // ['x', 'x', 'x']复制代码
  • 使用泛型
class GenericNumber
{ zeroValue: T; add: (x: T, y: T) => T;}let myGenericNumber = new GenericNumber
();myGenericNumber.zeroValue = 0;myGenericNumber.add = function(x, y) { return x + y; };复制代码
  • 指定泛型的默认类型
function createArray
(length: number, value: T): Array
{ let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result;}复制代码

原文连接: https://ts.xcatliu.com/

转载于:https://juejin.im/post/5b66845d6fb9a04fb40182ce

你可能感兴趣的文章
演示:取证分析IPV6组播地址的构成原理
查看>>
PowerShell-Exchange:统计每天邮件收发
查看>>
Exchange 2013部署系列之(二)先决条件
查看>>
6个技巧精准捕获百度知道问题
查看>>
Exchange server 2003迁移到2010后,手动更新地址列表,提示OAB Versions无效
查看>>
用Saltstack的modules和grains实现实时监控平台
查看>>
【统计商户24个月连续流水总月数存储过程】
查看>>
Silverlight实用窍门系列:42.读取拖动到控件上的外部txt和jpg文件,多外部文件的拖动【附带实例源码】...
查看>>
学习:java设计模式—Observer模式
查看>>
(转)使用 dom4j 解析XML
查看>>
估算,想爱你好难!- 视频分享第3弹!
查看>>
如何完美的将对话框设置成无边框无标题栏样式?
查看>>
HDU 114 Piggy-Bank
查看>>
音频基础知识及编码原理
查看>>
[转]Linux下的权限问题
查看>>
Notepad++搭建Python开发环境的一个小改进
查看>>
来自豆瓣的一个走过弯路的人(转)
查看>>
ios多线程学习笔记(1)
查看>>
scrollView的几个属性contentSize contentOffset contentInset
查看>>
POJ 1654 Area
查看>>