一篇快速入门TypeScript

353 阅读7分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

什么是TS

官网地址

TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准。

TypeScript 由微软开发的自由和开源的编程语言。

TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。

JavaScript 与 TypeScript 的区别

以下概念内容来自菜鸟教程 地址

TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。

TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。

image.png

为什么使用TypeScript

优点:

  1. 程序更容易理解:参数类型更明确,不需要手动调试就能知道什么类型
  2. 效率更高:代码调整、代码补全更方便
  3. 更少的错误:能够发现编译期间更多的错误,杜绝一些常见错误
  4. 非常好的包容性:完全兼容js,第三方库可以单独编写类型文件

缺点:

  1. 增加了学习成本
  2. 短期内增加了一些开发成本,类如变量类型定义等

安装使用

npm安装(全局,推荐全局安装)

npm install typescript -g

npm安装(局部)

npm install typescript --save-dev

验证

tsc -v

如果上一步提示没有tsc命令,执行以下步骤 (注意先使用管理员模式打开vscode试试有没有用)

安装

npx typescript

初始化

npx tsc --init

版本

npx tsc -v

image.png

编译命令

npx tsc

自动编译

npx tsc -w

npx和npm的区别

  1. npx侧重于执行命令的,执行某个模块命令。虽然会自动安装模块,但是重在执行某个命令。
  2. npm侧重于安装或者卸载某个模块的。重在安装,并不具备执行某个模块的功能。

HelloWord

  1. 新建一个test.ts,编写代码

const hello = (text) => {
    return 'hello ${text}';
}

hello('word')

2.编译生成js文件(tsc命令+ts文件)

image.png

ES6中的类型

基础类型

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol

对象类型

  • Object

它们在ts中的声明格式:let(var const) 变量名:类型=值。例如:let a:Number=1

注意还可以声明为any类型,但是可能会涉及到类型转换错误,通常不推荐使用

数组

声明方式:let(var const) 变量名:类型[]=[值]。例如:let arrayNumbers: number[] = [1, 2, 3]

数组常用方法

第一: push 和 pop (数组压入和弹出操作)
1、push可以每次压入一个或多个元素,并返回更新后的数组长度。
(如果参数是数组,则是将全部数组当做一个元素压入)
2、pop每次只会弹出结尾的元素,并返回弹出的元素。
(对空组数调用 pop() ,则返回undefined)


第二: unshift 和 shift (添加和删除数组头部数据)
1、unshift() 可向数组的开头添加一个或多个元素,并返回更新后的数组长度。
(unshift() 方法直接修改原有的数组,Internet Explorer 浏览器不支持)
2、shift() 删除数组的第一个元素,并返回被删除的元素的值
(shift() 方法直接修改原有的数组;数组是空直接返回 undefined 值)


第三: join (数组转换为字符串) :arr.join(separator)
1、join将数组各个元素是通过指定的分隔符进行连接成为一个字符串
(参数可选,如果省略该参数,则使用逗号作为分隔符)


第四: slice (返回选定数组范围的元素) :arrt.slice(start,end)
1、从已有的数组中选定的元素返回新的数组,从 start 到 end (不包括该元素)
(可使用负值从数组的尾部选取元素)
(end 未被规定,会选取从 start 到数组结尾的所有元素)


第五: splice (插入、删除或替换数组的元素):arr.splice(index,howmany,ele1,.....,eleX)
1、在index =2 的位置添加一个元素:arr.splice(2,0,"W")
2、新元素替换index =2 的位置元素 : arr.splice(2,1,"W")
3、新元素替换从 index= 2的位置开始的三个元素:arr.splice(2,3,"W")


第六: contact (将参数连接到数组 )
1、arr.concat(4,5)
2、arr.concat(arr2)
(参数可以是元素,也可以是数组)

元组(规定每个值类型的数组)

声明方式:let(var const) 变量名:[类型1,类型2,类型3]=[类型1的值,类型2的值,类型3的值]。例如:let arrayNumbers: [number,string,number] = [1, '2', 3]

需要注意的是类型可以用逻辑判断,例如:let arrayNumbers: [number | string, string, number] = ['1', '2', 3],也可以是let arrayNumbers: [number | string, string, number] = [1, '2', 3]

interface(接口)

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

接口通常用于来定义某种规范, 类似于你必须遵守的协议, 站在程序角度上说接口只规定了类里必须提供的属性和方法, 从而分离了规范和实现,增强了系统的可拓展性和可维护性;

示例: 这时候接口定义了属性以及属性类型,如果你定义一个接口类型的变量,需要遵循接口的规范。

interface user {
    id: number;
    name: string;
    age: number;
}

let test: user = {
    id: 1,
    name: 'test',
    age: 10
}

编译成js

var test = {
    id: 1,
    name: 'test',
    age: 10
};

function函数

使用function关键字声明,加上函数名、参数、返回值

示例:

function add(x: number, y: number): number {
    return x + y;
}
add(0, 3)

可选参数参数前加?,需要注意判断类型

function add(x: number, y: number, z?: number): number {
    if (typeof z === 'number') {
        return x + y + z;
    }
    return x + y;
}
add(0, 3, 1)

函数的表达式写法

const add1 = (x: number, y: number, z?: number): number => {
    if (typeof z === 'number') {
        return x + y + z;
    }
    return x + y;
}

add1(0, 3, 1)

enum枚举

枚举的作用是列举类型中包含的各个值,一般用它来管理多个相同系列的常量(即不能被修改的变量),用于状态的判断。这是一种无序的数据结构,把键映射到值上,可以理解为编译时键固定的对象,访问键时,ts将检查指定的键是否存在

实例:

enum enums{
    On = 'on',
    Off = 'off',
}

const a = 'on';
if(a === enums.On){
    console.log(a);
}

编译为js

enum enums{
    On = 'on',
    Off = 'off',
}

const a = 'on';
if(a === enums.On){
    console.log(a);
}

注意:如果是枚举都是常量,不参与计算,可以把枚举定义为常量枚举,提示效率(不会有很多的逻辑)

const enum enums{
    On = 'on',
    Off = 'off',
}

const a = 'on';
if(a === enums.On){
    console.log(a);
}

编译js后比上面代码量会更少

var a = 'on';
if (a === "on" /* enums.On */) {
    console.log(a);
}

generics泛型

泛型可以理解为宽泛的类型,通常用于类和函数,就像是一个占位符,在使用的过程中确定类型。

示例:

编写函数传入类型为泛型,参数类型也为泛型,这时根据ts的类型推断,a1就是number类型,a2就是string类型,这就是泛型的简单使用。

function getA<T>( a: T){
    return a;
}

let a1 = getA(1);

let a2 = getA('1');

泛型——约束泛型(extends)

可以使用泛型extends(java中的叫法叫继承)接口,这时候这个泛型在实际使用的时候必须有接口的方法或者属性,这就起到了约束的效果

示例:

这个示例中T继承了onlyOne,所以在实现getA方法时one参数是必须传的,否则就会报错通不过编译,这就起到了约束的作用,其他的因为是泛型所以传什么都行。

interface onlyOne{
    one: string
}

function getA<T extends onlyOne>(a :T): T{
    return a;
}

getA({one:'a',test:1,test1:2});

泛型在类和接口中使用

类中简单使用:


class A<T>{
    private a: T;
    public getA(){
        return this.a;
    }

    public setA(parms: T){
        this.a = parms;
    }
}

const a = new A<number>();
a.setA(1);

接口中简单使用:

interface B<K,V>{
    a1: K,
    a2: V,
}

let b1: B<string,number> = {a1:'a1',a2:1};
let b2: B<number,string> = {a1:1,a2:'a2'};

类型别名type

使用type关键字可以给一个复制的类型声明一个名字,可以达到复用的目的

示例:

type stringOrNumber = string | number
let b3: stringOrNumber;
b3 = '1';
b3 = 1;

字面量

在声明时给变量声明特定变量,只能让它等于这个变量值,一般无意义,需要结合type使用

平常使用:

const a: 1 = 1 

结合type以及‘|’

type parms = 'a'|'b'|'c'|'d'
let b: parms = 'a'
b='b'
b='c'

后记

本篇博客是对ts的入门,对于ts有基础的概念,以及对一些关键字的使用,后续会有进阶ts博文,以及实战ts博文。