看了最会的TypeScript入门

223 阅读6分钟

人狠话不多,ts的好处,为什么会诞生ts,发展过程这里没有介绍,简洁明了直接上手就好,如果有哪里不对的地方希望各位大佬多多指教。

环境搭建

编译环境安装

npm install typescript -g

查看版本,看看是否安装成功

tsc --version

为了方便运行,这里再安装一下ts-node

npm install ts-node -g npm install tslib @types/node -g

安装了ts-node后,后面运行ts文件的时候可以直接执行ts-node 文件名就可以

变量声明

let/const 标识符: 数据类型 = 赋值 比如:let age: number = 18 如果给let age: number = 'abc'会报错,因为前面已经给了number类型,不能再赋值其他的数据类型

变量的类型推断

在开发的过程,有时候为了方便,不需要在每个变量声明的时候都给加上类型,这时候就借助ts的特性来推断类型,比如下面的代码

let message="hello"
message=123 //会报错
//因为上面推断是字符串类型

类型

number类型

数字类型是我们开发中经常使用的类型,TypeScript和JavaScript一样,不区分整数类型(int)和浮点型 (double),统一为number类型。代码示例如下:

let num: number = 123
num = 222
boolean类型
let flag: boolean = true
string类型
let message1: string = 'hello world'

这里的string是小写,同时也支持ES6的模板字符串来拼接变量和字符串。

Array类型

数组的定义类型有两种方式

第一种

const names1: Array<string> = ['abc','cba']

Array后面的类型是string,表示这个数组只能添加string,如果数组中包含非string的数据类型,那么就会报错

第二种

const names2: string[] = ['abc','cba'] // 推荐这种写法
object类型
const info:object={
   name:'name'
}
null和undefined类型
let n1: null = null
let n2: undefined = undefined
any类型

在某些时候,我们无法判断一个数据的类型或者它存在变化的可能的时候这时候就可以使用any类型,代码示例如下:

let a:any='string';
a=123
let arr:any[]=[1,'abc']
unknown

unknown是TypeScript中比较特殊的一种类型,它用于描述类型不确定的变量。

function foo() {
    return "abc";
}

function bar() {
    return 123;
}

// unknown类型只能赋值给any和unknown类型
// any类型可以赋值给任意类型

let flag = true;
let result: unknown; // 最好不要使用any
if (flag) {
    result = foo();
} else {
    result = bar();
}
let message: string = result; //报错
let num: number = result; //报错

console.log(result);
void类型

通常用来指定一个函数时没有返回值的

function sum(num1: number, num2: number) {
    console.log(num1 + num2);
}

sum(20, 30);
never

表示永远不发生值的类型,如果一个函数中是一个死循环或者抛出一个异常,那么这个函数会返回东西吗?不会,那么写void类型或者其他类型作为返回值类型都不合适,我们就可以使用never类型

function bar(): never {
   throw new Error()
 }
元组类型tuple
  • 元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型
  • 数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。(可以放在对象或者元组 中)
const info: [string, number, number] = ["string", 18, 1.88]
const name = info[0]
函数的参数类型

函数是JavaScript非常重要的组成部分,TypeScript允许我们指定函数的参数和返回值的类型

  • 参数的类型注解 声明函数时,可以在每个参数后添加类型注解,以声明函数接受的参数类型
function sum(num1: number, num2: number) {
    return num1 + num2;
}

sum(123, 321);
  • 函数的返回值类型
function sum(num1: number, num2: number):number {
    return num1 + num2;
}

sum(123, 321);

在开发中,通常情况下可以不写返回值的类型(自动推导)

  • 匿名函数的参数 匿名函数与函数声明会有一些不同,该函数的参数会自动指定类型
const arr=['a','b']
arr.forEach(item=>{
   
})

这里并没有指定item的类型,但是item是一个string类型

对象类型

如果我们希望限定一个函数接受的参数是一个对象,这个时候要如何限定呢

function printPoint(point: {x: number, y: number}) {
  console.log(point.x);
  console.log(point.y)
}

printPoint({x: 123, y: 321})
可选类型
function printPoint(point: {x: number, y: number, z?: number}) {
  console.log(point.x)
  console.log(point.y)
  console.log(point.z)
}

printPoint({x: 123, y: 321})
printPoint({x: 123, y: 321, z: 111})
联合类型

联合类型是由两个或者多个类型组成的,表示可以是这些类型中的其中一种

function fn(id:number|string){
   console.log(id)
}
fn(123)
fn('abc')
类型别名

如果我们想要多个地方使用某个对象类型或者联合类型的时候,这时候就可以用到类型别名

type IDType = string | number | boolean;
type PointType = {
    x: number;
    y: number;
    z?: number;
};

function printId(id: IDType) {}
function printId2(id: IDType) {}

function printPoint(point: PointType) {}
function printPoint2(point: PointType) {}
类型断言as

有时候无法获取具体的类型信息就可以使用类型断言

const el = document.getElementById("why") as HTMLImageElement
el.src = "url地址"
非空类型断言
// message? -> undefined | string
function printMessageLength(message?: string) {
  // if (message) {
  //   console.log(message.length)
  // }
  // vue3源码
  console.log(message!.length)
}

printMessageLength("aaaa")
printMessageLength("hello world")
字面量推理
type Method = "GET" | "POST";
function request(url: string, method: Method) {}

type Request = {
    url: string;
    method: Method;
};

const options = {
    url: "https://www.coderwhy.org/abc",
    method: "POST",
} as const;

request(options.url, options.method);
函数类型

示例

type fn1=(num1:number,num2:number)=>void
function calc(fn:fn1){
  console.log(fn(20,30))
}

函数的可选参数

function foo(x: number, y?: number) {

}

foo(20, 30)
foo(20)
接口

在前面有介绍过type可以声明一个对象类型,接口也可以

interface Point{
   x:number
   y:number
}

接口的继承

interface ISwim {
  swimming: () => void
}

interface IFly {
  flying: () => void
}


interface IAction extends ISwim, IFly {

}

const action: IAction = {
  swimming() {

  },
  flying() {
    
  }
}
接口interface和type区别
  • 如果是定义非对象类型,通常推荐使用type,比如Direction、Alignment、一些Function
  • interface 可以重复的对某个接口来定义属性和方法
  • 而type定义的是别名,别名是不能重复的
交叉类型

所有的都要满足

type WType = number & string
泛型

参数的类型参数化

function fn(arg:number):number{
  return arg
}

上面的代码虽然实现了,但是不适用于其他类型,比如:string,boolean等类型,可能会有人说any可以,但是如果这里适用any就失去了类型的信息 所以这时候就需要泛型了

function sum <Type>(num:Type):Type{
  return num
}
sum<number>(20)  //调用方式1:明确的传入类型
sum('abc') //调用方式2

多个参数的情况

function foo<T, E, O>(arg1: T, arg2: E, arg3?: O, ...args: T[]) {

}

foo<number, string, boolean>(10, "abc", true)

泛型+接口的使用

interface IPerson<T1 = string, T2 = number> {
    name: T1;
    age: T2;
}

const p: IPerson = {
    name: "why",
    age: 18,
};

暂时先到这里