Typescript快速入门笔记

206 阅读6分钟

前言

官网www.typescriptlang.org/

使用管理员打开cmd,然后输入npm install -g typescript

慕课网免费课程www.imooc.com/video/23202

typescript工具流

开发环境配置

2-2 main.ts

let hello = "hello world"

console.log(hello)

\

JavaScript工具流

npm init 安装配置

npm install --save-dev lite-server 安装对需要的文件 轻量级服务器lite-server

然后可以再终端直接输入npm satrt运行代码

浏览器检测到变化后自动进行变化

TS的基础类型

变量声明

尽量使用let

var会使得作用域混乱

// 课程3-1 变量声明
var number1 = 1;
let number2 = 2;
const number3 = 3;

function doSomething(){
    // 使用var会使得变量i突破作用域
    for(var i = 0;i < 5;i++){
        console.log(i)
    }
    console.log(i)
}
doSomething();

类型

  • boolean
  • string
  • number
  • array
  • undefined
  • object

新增的

  • tuple
  • enum
  • void
  • never
  • any

高级类型

  • union组合类型
  • Nullable可空类型
  • literal预定义类型

Number 数字类型

整数、浮点数、正负数

function add(n1:number,n2:number){
    return n1+n2
}
// 如果不对变量进行限制的话,使用字符串也可以运行
console.log(add(number1,number2))

String字符串类型

"hello"'hello'`hello`

``反引号,可以创建一个字符串模板

let str = `我是$(firstName)`

Boolean布尔类型

真假

// 会进行自动指定,为布尔类型
let isTrue = true;
// isTrue = "false" 错误

// 也可以自己手动定义
let total:number = 0
let firstName:string = "你好呀"
let str = `我是$(firstName)`

数组Array

let list1:number[] = [1,2,3,4]
// 泛型
let list2:Array<number> = [1,2,3,4]
let list3 = [1,2,3,4]

let list4 = [1,"ddd"] //两种类型
let list5: any[] = [1,"dss",true]

元组 tuple

// Tuple 固定顺序
let people : [number,string] = [1,"ddd"]
// people[0] = "ddd" //出错 只能为数字类型
// people[1] = 1 //出错 只能为string类型
// people[2] = 2 //出错 不可以增加
// 元组固定长度,固定类型

// people.push(3) 没有出错,但是是错误,因为只能由两个不能够进行增加
// 联合类型
let people1 = [1,"ddd"]

联合类型 Union

就是同时标记两个属性,任选一个成立

let union : string | number
union = 2
union = "dddd"
//union = true //错误

let union2 : number | string | boolean | string[]

function add1(n1:number | string,n2 :number | string){
    if(typeof n1 === "string" || typeof n2 === "string"){
        return n1.toString() + n2.toString()
    }else{
        return n1 + n2   
    }
}

let addNumber = add1(1,3)
let addString = add1("123","3")
console.log(addNumber)
console.log(addString)

字面量类型 literal

// 字面量类型 literal
let union3: 0 | 1| 2
union3 = 1
// union3 = 4 //出错
let literal : 1 | "2" | true | [1,2,3,4]
function add1(
    n1: number | string, 
    n2: number | string,
    // 加上一个字面量类型
    resultType:"as-number" | "as-string") {
    if(resultType === "as-string"){
        return n1.toString() + n2.toString();
    }
    if (typeof n1 === "string" || typeof n2 === "string") {
        return n1.toString() + n2.toString();
    } else {
        return n1 + n2;
    }
}

let addNumber = add1(1,3,"as-number");
let addString = add1(1,3,"as-string");
console.log(addNumber);
console.log(addString);

对变量的取值加上字面量类型,指定输出值

枚举 enum

枚举就是对变量赋予指定的值,默认按顺序赋值

// 枚举类型 Enum
enum Color {
    red, // 0
    green, // 1
    blue // 2
}
let color = Color.blue
console.log(color) //2

enum Color2 {
    red = 5,
    green = 10,
    blue = 1
}

enum Color3 {
    red = "red",
    green = "green",
    blue = 1
}

any和unknow

any能够使得代码快速成型,unknow会更加准确一些,更加安全

// 3-7 any和unknown
// any代码
let randomValue: any = 666;
randomValue = true
randomValue = 1
randomValue = "true"
randomValue = {}
randomValue()
randomValue.toUpperCase() //不存在的,写出来没有报错,编译的时候出错
let randomValue: unknown = 666;
randomValue = true
randomValue = 1
randomValue = "true"
randomValue = {}
if (typeof randomValue === 'function'){
    randomValue()
}
if (typeof randomValue === 'string'){
    randomValue.toUpperCase() 
}

void,undefined 和never

void是表示根本不存在

undefined表示还没有定义

never 表示永远无法完成

function printReasult():void {
    console.log("hello-")
}
function printReasult1():undefined {
    console.log("hello")
    return
}
function throwError1(message:string,errCode:number):never {
    throw {
        message,
        errCode
    }
}

throwError1("not found",404)
function whileLoop():never {
    while(true){
        console.log(1)
    }
}
whileLoop()

类型适配

  • 变量前面加上,例如 message
  • 变量后面加上类型,例如 message as string

注意每次使用的时候需要注意自己要转化的类型

// 3-9 类型适配(类型断言) Type Assertions
let message : any;
message = "abc" //虽然赋值是字符串,但是实际上还是any类型

// 使用括号和三角
let dd1 = (<string>message).endsWith("s")
// 使用as形式
let dd2 = (message as string).endsWith("s")

函数类型

  • 给参数绑定类型
  • 调用函数时候,需要对应数目和类型
  • 给参数变量后加上?,表示可选参数
  • 也可以直接给参数赋值
let log = function(message) {
    console.log(message)
}
// 给参数绑定类型
// 调用函数时候,需要对应数目和类型
// 给参数变量后加上?,表示可选参数
// 也可以直接给参数赋值
let log1 = (message:string,age?:number) => {
    console.log(age)
}

// log1("hello","123") //错误,因为第一个参数不是数字
log1("hello")

typescript面向对象

object对象类型

  • 对象中不存在的变量会报错
  • 如果不自己手动定义的话,对象内部的类型也会被自动定义好
const person = {
    firstName : "ddd",
    age:12
}
console.log(person.age)
// 对象中不存在的变量会报错
// 对象内部的类型也会被定义好
// key to type 键类型对
const person1:{
    firstName:string,
    age:number
} = {
    firstName : "ddd",
    age:12
}

Interface接口

之前对变量进行限制的时候,是有多种基础类型的,是可以通过定义类型的

```let drawPoint1 = (point:Point) => {`

console.log({x:point.x,y:point.y})

}

Point来限制变量point

限制xy的变量类型,限制xynumber类型

interface Point{
    x:number;
    y:number
}
let drawPoint = (x,y) => {
    console.log({x,y})
}
// 面向对象的方式,传入参数
let drawPoint1 = (point:Point) => {
    console.log({x:point.x,y:point.y})
}
drawPoint1({x:122,y:12})
// drawPoint1({x:"122",y:"12"}) //出错 ,变量值的类型不匹配
// drawPoint1({weather:"干燥",temperature:"1oc"}) //出错,变量不匹配

// 对内部的变量加以限制
// 限制内部变量为两个,且都为number类型
// let getDistances = (a:PointerEvent,b:Point) =>{
//     // 
// }

interface Point{
    x:number;
    y:number
}

class类

类就是对对象的描述

  • 公有属性
  • 私有属性
  • 传参
  • 成员方法
  • 私有成员方法
  • 封装
  • 继承
  • 多态

使用interface来定义接口IPoint

其中有xydrawPointgetDistances

interface IPoint{
    x:number;
    y:number,
    // 用来描绘点数
    drawPoint:()=>void;
    // 用来计算两点间的距离
    getDistances:(p:IPoint) => number;
}

接下来实现一个类

接口的实现接口 IPoint implements 实现

class Point implements IPoint {
    x: number;
    y: number;
    drawPoint = () =>{
        console.log("x: ",this.x," y: ",this.y);
    }
    // 计算距离
    getDistances = (p:IPoint) => {
        return Math.pow(p.x - this.x,2) + Math.pow(p.y-this.y,2)
    }
}
// 高内聚低耦合 

创建实例需要使用new, 对象实例化后就产生了对象

const point = new Point() //对象object,实例instance
// 对x和y进行初始化
point.x = 2;
point.y = 3
point.drawPoint()

使用构造函数constructor进行初始化,可以给变量名之后加上这样子创建变量的时候,可以不给变量加上名字

javascript的构造函数不可以进行重载

x: number;
y: number;
constructor(x?:number,y:number = 2){
  this.x = x;
  this.y = y
}

使用访问修饰符,就会再构造变量的同时,函数会自动生成所需的成员变量

  • public
  • private
    constructor(public x:number = 1,public y:number = 2){
    }

\

Access Modifier访问修饰符

  • public
  • private
  • protected

上面的构造函数可以改成:

constructor(private x:number = 1,public y:number = 2){
  // this.x = x;
  // this.y = y
}

使用getter和setter来对变量访问和赋值的时候进行限制

添加一个函数setX

setX = (value:number) => {
  if(value < 0){
    throw new Error("value 不能小于0")
  }
  this.x = value
}

可以建立一个内部和外部的缓冲带

point.setX(10)
point.setX(-10) //Error: value 不能小于0

建立一个getX函数

getX = () => {
  return this.x
}

使用它自带的set,可以向定义一个变量一样

对x进行设置

set X(value: number){
  if(value < 0){
    throw new Error("value 不能小于0")
  }
  this.x = value           
}
get X(){
  return this.x
}

然后可以向属性一样进行访问和赋值

point.X  = 12
console.log(point.X)   

Module模块

将定义point的相关内容放入单独的一个ts文件中,

然后对其中的class前面加上一个export

然后在前面的文件通过import {类名} from "文件地址"

import {Point} from "./point"

Generics泛型

  • 使用类型+[]的方式来定义数组
  • 使用泛型的类型来定义数组 Array<类型>
// 使用类型+[]的方式来定义数组
let list1: number[] = [1,2,3,4]
// 使用泛型的类型来定义数组 Array<类型>
let list2: Array<number> = [1,2,3,4]

定义一个泛型

let lastInArray = (arr:Array<number>) => {
    return arr[arr.length - 1]
}
     
const l1 = lastInArray([1,2,3,4]) 

但是l1变为lastInArray(['1',"2","3"])

就会出错

这时候可以通过在函数前面加上<T>进行动态类型,例如let lastInArray = <T>(arr:Array<T>)

let lastInArray = <T>(arr:Array<T>) => {
    return arr[arr.length - 1]
}

const l1 = lastInArray([1,2,3,4])
// 加上<string>指定类型
const l2 = lastInArray<string>(['1',"2","3"])
const l3 = lastInArray<string|number>(["a","b","c",1,2,3])

这时候的化,可以看到,语言会自动定义好类型,比如此时 l1的类型为number,l2的类型为string

可以在函数前面加上<T,Y>然后后面对应指定的类型,然后进行输出,就可以自己定义类型了

let makeTuple = <T,Y>(x:T,y:Y) => [x,y]

let makeTuple = <T,Y>(x:T,y:Y) => [x,y]

const v1 = makeTuple(1,"one")
const v2 = makeTuple<boolean,number>(true,1)