初识Typescript | 青训营笔记

121 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的第七天

TS基本介绍

TypeScript是微软开发的一个开源的编程语言,通过在JavaScript的基础上添加静态类型定义构建而成。TypeScript通过TypeScript编译器或Babel转译为JavaScript代码,可运行在任何浏览器,任何操作系统。

我们知道:

JS动态类型(执行阶段才进行类型匹配)、弱类型语言

TS静态类型(编译提前执行)、弱类型语言

静态动态、强类型弱类型分别是什么意思呢。下面来进行介绍。

概念介绍

静态与动态编程语言

变量类型在编译过程中被检查的是静态编程语言

变量类型在运行过程中被检查的是动态编程语言

弱类型与强类型的概念

强类型语言:强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。

弱类型语言:数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。

为什么使用TS?

可读性增强:基于语法解析TSDoc,ide增强

可维护性增强:在编译阶段暴露大部分错误

多人合作的大型项目中,获得更好的稳定性和开发效率

包含于兼容所有JS特性,支持共存

支持渐进式引入与升级

安装

npm install -g typescript

在终端输入:tsc -v

如果出现版本号则说明安装成功

注意!在编写ts文件时,常常会出现报错显示重复声明,为了解决这个问题可以在扩展商店里安装deno


Ts编译

  1. 在终端输入tsc --init,这样会在文件夹下自动生成tsconfig.json文件(也可以自动手动创建文件) tsconfig.json是ts的配置文件,ts编译器可以根据它的信息来对代码进行编译,include用来指定哪些ts文件需要被编译

  2. 然后在终端输入tsc,则会将所有ts文件编译成js文件 如果想要ts文件每次自动编译成js文件,可以右键终端,点击运行任务,选择tsc:监视-XXX/tsconfig.json

基础类型

let str: string = "jimmy";
let num: number = 24;
let bool: boolean = false;
let u: undefined = undefined;
let n: null = null;
let obj: object = {x: 1};
let big: bigint = 100n;
let sym: symbol = Symbol("me"); 

注意

  • null和undefined是所有类型的子类型,也就是说你可以把null和undefined赋值给其他类型,但是如果在tsconfig.json中指定了"stricNullChecks":true,null和undefined只能赋值给void和它们各自的类型

  • number和bigint

虽然两者都表示数字,但是这两个类型不兼容

let big: bigint =  100n;
let num: number = 6;
big = num;//!报错:不能将number分配给bigint
num = big;//!报错:不能将bigint分配给number
  • 数组

对数组的定义方式

//1.在某元素类型后面加上[]
//string[] 表示字符串数组
let m:string[];
m = ['a','b','c'];
//number[]表示数值数组

let p:number[];
//2.使用数组泛型
let j:Array<number>;

!!一些新的

  • 任意类型 any 声明为any的变量可以赋予任意类型的值
  • unkown表示未知类型的值,typescript推荐使用unkown,因为unkown是类型安全的

any与unkown的区别

any类型的可以赋值给任意变量;unknown实际上就是一个类型安全的any,不能直接赋值给其他变量

let a:unkown;
let b:any;
let k : boolean | string;
k = b;
k = a;//!会报错
  • 元组 元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。
let x: [string, number];
x = ['Runoob', 1];    // 运行正常
x = [1, 'Runoob'];    // !报错
console.log(x[0]);    // 输出 Runoob
  • 枚举 enum 枚举类型用于定义数值集合 枚举类型支持枚举值到枚举名的正、反向映射
enum Color {Red, Green, Blue};
let c: Color = Color.Blue;
console.log(c);    // 输出 2
  • void 用于表示方法返回值的类型,表示该方法没有返回值
function fn():void{
    return undefined;
    //return null;   会报错
}
  • never 表示永远不会返回结果,是其他类型(包括null和undefined)的子类型
function fn1():never{
    throw new Error('出错了!')
}

注意:参数名后加?:表示为可缺省参数

联合/交叉类型 联合类型 |表示一个值可以是几种类型之一 交叉类型 & 各种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性

泛型

我们需要一种方法使返回值的类型与传入参数的类型是相同的。 这里,我们使用了 类型变量,它是一种特殊的变量,只用于表示类型而不是值

function identity<T>(arg: T): T {
    return arg;
}

学习参考

泛型的基本使用

  • 处理函数参数

我们可以用泛型来解决函数输入输出一致的问题。泛型中的T就像一个占位符、或者说一个变量,在使用的时候可以把定义的类型像参数一样传入,它可以原封不动地输出。

!type和interface也可以定义函数类型

type Print = <T>(arg: T) => T
const printFn:Print = function print(arg) {
    console.log(arg)
    return arg
}

//interface
interface Iprint<T> {
    (arg: T): T
}

function print<T>(arg:T) {
    console.log(arg)
    return arg
}

const myPrint: Iprint<number> = print
  • 默认参数

如果要给泛型加默认参数,可以向下面这样写

interface Iprint<T = number> {
    (arg: T): T
}

function print<T>(arg:T) {
    console.log(arg)
    return arg
}

const myPrint: Iprint = print
  • 处理多个函数参数
function swap<T, U>(tuple: [T, U]): [U, T]{
    return [tuple[1], tuple[0]]
}

这样就可以实现了元组第 0 项和第 1 项类型的控制