TypeScript 记录

前言

这两天系统的看了一遍文档,记录一下基础定义和用法。文档上有的定义就不介绍了,只记录基础概念的理解和用法。

先放一下看的这些文档: Runoob | TypeScript | xcatliu

简介

官网对 TypeScript 的定义:

Typed JavaScript at Any Scale. 添加了类型系统的 JavaScript,适用于任何规模的项目。

TypeScript 的核心设计理念:

在完整保留 JavaScript 运行时行为的基础上,通过引入静态类型系统来提高代码的可维护性,减少可能出现的 bug。

关于更多的介绍可以看 xcatliu 作者的这章:什么是 TypeScript

个人理解简单概括一下:

因为 JavaScript 是一门解释型语言,没有编译阶段,在运行时才会进行类型检查,往往会导致运行时错误。而 TypeScript 在运行前需要先编译为 JavaScript,在编译阶段就会进行类型检查,在很大程度上弥补了 JavaScript 的缺点。

TypeScript 只会在编译时对类型进行静态检查,如果发现有错误,编译的时候就会报错。而在运行时,与普通的 JavaScript 文件一样,不会对类型进行检查。

引用总结

  • TypeScript 是添加了类型系统的 JavaScript,适用于任何规模的项目。
  • TypeScript 是一门静态类型、弱类型的语言。
  • TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性。
  • TypeScript 可以编译为 JavaScript,然后运行在浏览器、Node.js 等任何能运行 JavaScript 的环境中。
  • TypeScript 拥有很多编译选项,类型检查的严格程度由你决定。
  • TypeScript 可以和 JavaScript 共存,这意味着 JavaScript 项目能够渐进式的迁移到 TypeScript。
  • TypeScript 增强了编辑器(IDE)的功能,提供了代码补全、接口提示、跳转到定义、代码重构等能力。
  • TypeScript 拥有活跃的社区,大多数常用的第三方库都提供了类型声明。
  • TypeScript 与标准同步发展,符合最新的 ECMAScript 标准(stage 3)。

TypeScript 的命令行工具安装方法如下:

npm install -g typescript
复制代码

以上命令会在全局环境下安装 tsc 命令,安装完成之后,我们就可以在任何地方执行 tsc 命令了。

编译一个 TypeScript 文件很简单:

tsc hello.ts
复制代码

我们约定使用 TypeScript 编写的文件以 .ts 为后缀,用 TypeScript 编写 React 时,以 .tsx 为后缀。

基础概念

基础类型

菜鸟教程列的这个 TypeScript 基础类型 很清晰。 更详细一些看 官方文档

  • 任意类型 any - 声明为 any 的变量可以赋予任意类型的值。
  • 数字类型 number - 双精度 64 位浮点值。它可以用来表示整数和分数。
  • 字符串类型 string - 一个字符系列,使用单引号或双引号来表示字符串类型。
  • 布尔类型 boolean - 表示逻辑值:true 和 false。
  • 数组类型 - 声明变量为数组。
  • 元组 - 用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。
  • 枚举 enum - 枚举类型用于定义数值集合。
  • void - 用于标识方法返回值的类型,表示该方法没有返回值。
  • null - 表示对象值缺失。
  • undefined - 用于初始化变量为一个未定义的值。
  • never - never是其他类型(包括 null 和 undefined)的子类型,代表从不会出现的值。

类型推论

类型推论:TypeScript 会在没有明确的指定类型的时候推测出一个类型。

let num = 'seven' // 等价于 let num: string = 'seven'
num = 7;  // 错误
复制代码

如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查。

let num;  // 等价于 let num: any; 定义时未赋值被推断成 any 类型
num = 'seven'; // 正确
num = 7;  // 正确
复制代码

联合类型

联合类型表示取值可以为多种类型中的一种。使用 | 分隔每个类型。

let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven'; // 正确
myFavoriteNumber = 7;      // 正确
myFavoriteNumber = true;  // 错误

// 将联合类型作为函数参数使用:
function disp(name:string|string[]){...}

// 我们也可以将数组声明为联合类型:
var arr:number[]|string[];
复制代码

接口

接口是一系列抽象方法的声明,是一些方法特征的集合,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。

// 定义一个接口 Person
interface Person { 
  readonly id: number;  // 只读属性
  firstName: string;
  lastName?: string;  // ? 问号代表可选属性
  sayHi:() => string;
  [propName: string]: any; // 任意属性 - 一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
  // commandline:string[] | string | (()=>string); // 联合类型
}
// 赋值的时候,变量的形状必须和接口的形状保持一致,多或者少了属性或方法都会报错。
let tom: Person = {
   id: 888,   // 初始化 - 只读属性初始化之后不允许再赋值了
   firstName: 'Tom',
   sayHi: ():string =>{return "Hi"}
}

// 接口继承  继承的各个接口使用逗号 , 分隔。
//单接口继承语法格式:
//Child_interface_name extends super_interface_name

//多接口继承语法格式:
//Child_interface_name extends super_interface1_name, super_interface2_name,…,super_interfaceN_name

复制代码

数组的类型

在 TypeScript 中,数组类型有多种定义方式,比较灵活。

// 定义一个number类型的数组,数组中只能包含number类型
let num: number[] = [1,2,3,4];

//定义一个string类型的数组,数组中只能包含string类型
let strArr: string[] = ['a','b','c']

// 也可以使用数组泛型Array<elemType> 来表示数组:
let arr: Array<number> = [1,2,3]

// 定义一个任意类型的数组
let list: any[] = ['xcatliu', 25, { website: 'http://xcatliu.com' }];

// 用接口表示数组 - 常用来表示类数组
interface NumberArray {
    [index: number]: string; // 数组的索引index设置为 number 类型,元素值设置为 string 类型
}
let fibonacci: NumberArray = ['a','b','c'];
复制代码

函数的类型

详细文档

函数需要把输入和输出都考虑到:

// 参数x,y都必须传入number类型,多或者少传参都是不允许的
// 函数返回值也定义了必须为 number 类型
function sum(x: number, y: number): number {
    return x + y;
}
复制代码

类型断言

类型断言可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。

类型断言有两种等价形式:

  • 值 as 类型
  • <类型>值

在 tsx 语法(React 的 jsx 语法的 ts 版)中必须 值 as 类型

类型推论是 TS 的自主行为,类型断言是我们要自行更改类型的手动行为。不要滥用类型断言,否则可能会导致运行时错误。

元组

元组中允许存储不同类型的元素,元组可以作为参数传递给函数。

    var tuple_name = [value1,value2,value3,...value n]

    // 声明一个元组并初始化:
    var mytuple = [10,"Runoob"];

    //访问元组
    mytuple[0];  // 10

    // push() 在元组最后面添加元素
    mytuple.push(12) // [10,"Runoob",12]

    // pop() 从元组中移除最后一个元素,并返回移除的元素
    mytuple.pop()  // 12

    // 更新元组
    mytuple[0] = 121;  // [121,"Runoob"]

    // 解构元组
    var [x,y] = mytuple; // x => 121  y => "Runoob"
复制代码

枚举

枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。

enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};

console.log(Days["Sun"] === 0); // true
console.log(Days["Mon"] === 1); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // true

console.log(Days[0] === "Sun"); // true
console.log(Days[1] === "Mon"); // true
console.log(Days[2] === "Tue"); // true
console.log(Days[6] === "Sat"); // tru
复制代码

泛型

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

function createArray<T>(length: number, value: T): Array<T> {
    let result: T[] = [];
    for (let i = 0; i < length; i++) {
        result[i] = value;
    }
    return result;
}

createArray<string>(3, 'x'); // ['x', 'x', 'x']
复制代码

声明文件

  // 声明文件以 .d.ts 为后缀,例如:
  runoob.d.ts
  // 声明文件或模块的语法格式如下:
  declare module Module_Name {}
  // TypeScript 引入声明文件语法格式:
  <reference path="runoob.d.ts" />
复制代码

总结

emmm.. 感觉就是文档的复制啊喂!!(╯‵□′)╯︵┻━┻ !!还没有复制完全(╯‵□′)╯︵┻━┻

好累,就这吧,当做是复习了一遍吧,基础类型,联合类型,类型推论,类型断言,接口,元组,枚举,类,泛型,别名,命名空间,声明文件等,这些概念看过之后就清晰多了,又是努力的一天啊,我真棒(^▽^)。

end.

Guess you like

Origin juejin.im/post/7039999158396125198