TypeScript 是JacaScript的超集 (包含js ES567语法),同时也新增了一些语法,例如类型和面向对象的。但是新增的这部分语法不能被浏览器和node.js无法识别并执行的,所以就需要一个工具将ts代码转换成浏览器、node.js识别的代码

安装ts前提要先安装node.js(这里不多说直接官网下载对应版本选择安装路径下一步就好了)

node.js安装下载地址 https://nodejs.org/zh-cn/

安装完成 查看对应版本号是否安装成功

node -v

全局安装ts

npm install -g typescript

cmd命令行查看是否安装完成

tsc -v

tsc负责将ts代码转换成浏览器、node.js识别的代码

这样有一个问题 每次执行ts文件都需要执行 tsc xxx.ts 才能去把ts文件转换成js文件,再去node xxx.js运行文件。试想一下项目如果有很多ts文件,这样执行起来就非常的麻烦。然而就需要一个工具来自动帮我们进行转换。

安装ts-node工具 

npm install -g ts-node

使用方法

#将ts文件转换成js,再自动执行该文件---node xxx.js
ts-node xxx.ts

angular 小程序 vue3.0 react

TyprScript 数据类型 | 变量

1.在声明变量的时候,需要指定变量类型 ,变量一旦指定数据类型,则该变量只能赋值类型的数据

// let 变量名: 变量类型

let name: string;
let age: number;

age = 18; //正确写法,赋值必须为number类型
age = "nian" //错误写法

2.TypeScript兼容JavaScript所有数据类型

// JavaScript 原有数据类型
string number boolean null undefined Symbol Array Obeject

// ts新增数据类型
tuple 元组 enum 枚举 any 任意类型 never void

3.联合数据类型

// 变量取值可以是这两种中的一种
let name: string | number;

name = "jeason Li";
name = 18;

4.any类型

// any为任意类型 可以存储任意类型数值
let name: any;

name = {};
name = "";
name = 123;
name = false;

5.数组类型

// 方式一: let 数组名: 类型[] = [值1,值2] 
let name: string[] = ['张三','李四','王五'];

// 方式二: let 数组名: Array<类型> = [值1,值2]
let name: Array<string> = ['张三','李四','王五'];

6.元组类型

#一个规定了元素数量和每个元素类型的数组,而每个元素的类型可以不相同

#let 元组名: [类型1,类型2,类型3] = [值1,,值2,值3]
let name: [string,number,boolean] = ['张三',22,true]

7.枚举类型

// 枚举用于状态标识等

// 声明语法
enum 枚举名{
    枚举项1 = 枚举值1,
    枚举项2 = 枚举值2,
    ...
}

enum sex{
    M = "男",
    F = "女"
}

// 枚举值可以省略,规则如下
enum sex{
    M,
    F
}

// 不设定枚举值 枚举的默认值
enum sex{
    M = 0,
    F = 1
}

8.void类型

// void 代表没有返回值,例如下面两个ts方法所示

// 方法返回值为string类型
function hello(): string{
   return "hello";
}

// void 不需要return返回
function hello(): void{
    console.log("hello wodl!");
}

9.never类型  never类型是ts的底部类型 ts中所有的类型都是never的父类型

// 在ts中代表不存在值的类型,常用作为抛出异常或无限循环的函数返回类型


// 死循环
function test(): never{
    while(true){}
}

// 抛出异常
function test(): never{
    throw new Error("服务器错误");
}

TyprScript 函数

1.声明函数

function test(): 返回值类型{
    
}

// 字符串
function test(): string{
    return "hello";
}

// void 无返回值类型
function test(): void{
    console.log("不需要返回")
}

// 数字
function test(): number{
    return 123;
}

// 布尔值
function test(): boolean{
    return true;
}

....

2.函数传参

// 声明test()方法
function test(形参1:类型 形参2:类型): string{
    return "hello";
}
// 调用 注意实参和形参类型必须一致
let test1 = test(实参1,实参2);

function test(username: string age: number): string{
    return "姓名:"+username+",年龄:"+age;
}

let test1 = test("张三",22);

3.函数可选参数,默认值

// 可选参数语法
function 函数名(形参 ? : 类型): 返回值类型{
    
}

// 函数名()
// 函数名(实参)


// 实例
function test(username ? : string): string{
    return "姓名:"+username;
}
test();
test("张三");

// 默认值语法
function 函数名(形参: 类型 = 默认值1): 返回值类型{
    
}

// 实例
function test(username: string = '张三',age: number): string{
    return "姓名:"+username+",年龄:"+age;
}

test(undefind,22);

4.剩余参数

// resOfNum 表示剩余的参数放在了一个number类型的数组中
// 剩余参数是放在函数所有参数的最后
function test(username: string,age: number, ...resOfNum: number[]): void{
    console.log(username) // 张三
    console.log(age) // 18
    console.log(resOfNum) // [10,11,12] 这里就是剩余参数
}

test('张三',18,10,11,12)

5.函数重载

TyprScript 接口

 

1.基础类型

/*
* readonly 表示当前属性只读
* sex? 表示当前属性可有可无
*/
interface Person{
    readonly id: number,
    name: string,
    age: number,
    sex?: string
}

// 定义一个对象,该对象的类型就是我定义的Person接口类型
let person1: Person = {
    id: 1,
    name: '张三',
    age: 18
}

// person1.id = 100 // 报错因为id是只读属性不能更改
person1.sex = '男'

2.函数类型

// 声明一个函数接口
interface ISearchFunc(){
    // 定义一个函数,参数是name和age 返回值是string
    (name:string,age:number) :string
}

const person:ISearchFunc = function (name:string,age:number):string{
    return `我的名字是${name},芳龄${age}`
}

console.log(person('刘亦菲',18))

3.类类型

/* 
类类型: 实现接口
1. 一个类可以实现多个接口
2. 一个接口可以继承多个接口
*/

interface Alarm {
  alert(): any
}

interface Light {
  lightOn(): void
  lightOff(): void
}

class Car implements Alarm {
  alert() {
      console.log('Car alert')
  }
}

// 一个类可以实现多个接口
class Car2 implements Alarm, Light {
  alert() {
    console.log('Car alert')
  }
  lightOn() {
    console.log('Car light on')
  }
  lightOff() {
    console.log('Car light off')
  }
}

// 接口继承接口
interface LightableAlarm extends Alarm, Light {}

TypeScript 泛型

1.函数泛型

// 普通写法
function createArray(value: any, count: number): any[] {
  const arr: any[] = []
  for (let index = 0; index < count; index++) {
    arr.push(value)
  }
  return arr
}

const arr1 = createArray(11, 3)
const arr2 = createArray('aa', 3)
console.log(arr1[0].toFixed(), arr2[0].split(''))

// 泛型写法
function createArray2 <T> (value: T, count: number) {
  const arr: Array<T> = []
  for (let index = 0; index < count; index++) {
    arr.push(value)
  }
  return arr
}
const arr3 = createArray2<number>(11, 3)
console.log(arr3[0].toFixed())
// console.log(arr3[0].split('')) // error
const arr4 = createArray2<string>('aa', 3)
console.log(arr4[0].split(''))

2.多个泛型参数的函数

// 一个函数可以定义多个泛型
function swap <K, V> (a: K, b: V): [K, V] {
  return [a, b]
}
const result = swap<string, number>('abc', 123)
console.log(result[0].length, result[1].toFixed())

3.泛型接口

interface IbaseCRUD <T> {
  data: T[]
  add: (t: T) => void
  getById: (id: number) => T
}

class User {
  id?: number; //id主键自增
  name: string; //姓名
  age: number; //年龄

  constructor (name, age) {
    this.name = name
    this.age = age
  }
}

class UserCRUD implements IbaseCRUD <User> {
  data: User[] = []
  
  add(user: User): void {
    user = {...user, id: Date.now()}
    this.data.push(user)
    console.log('保存user', user.id)
  }

  getById(id: number): User {
    return this.data.find(item => item.id===id)
  }
}


const userCRUD = new UserCRUD()
userCRUD.add(new User('tom', 12))
userCRUD.add(new User('tom2', 13))
console.log(userCRUD.data)