1.TypeScript安装和基础

安装TypeScript

# 全局安装
npm install -g typescript

# 更新
npm update typescript -g

# 查看TypeScript版本
tsc -v

TS编译成JS

hello.ts

console.log('hello typescript')
tsc hello.ts

hello.js

console.log('hello typescript');

优化编译

解决TS和JS冲突问题

# 生成配置文件,tsconfig.json
tsc --init

# 自动编译
tsc --watch
# 当ts有错误的时候不允许编译成js
tsc --noEmitOnError --watch

显示类型

变量名:类型

function print(name: string, date: Date){
    console.log(`hello ${name}, 现在是:${date}`)
}

print('小明', new Date())

降级编译

在tsconfig.json配置文件中配置,找到 Language and Environment 这个位置

将target的值修改为:es5/es3

{
  // "target": "es2016",
  "target": "es5",
}

hello.ts 文件

// console.log('hello typescript')

function print(name: string, date: Date){
    console.log(`hello ${name},  todat is ${date}`)
}

print('小明', new Date())

编译es5语法hello.ts文件

// console.log('hello typescript')
function print(name, date) {
    console.log("hello ".concat(name, ",  todat is ").concat(date));
}
print('小明', new Date());

严格模式

一般默认情况下开启严格模式

{
  "strice": true,
  "noImplicitAny": true,
  "strictNullChecks": true,
}

基础类型

类型
string
number
boolean

base-type.ts

let str : string = 'hello string'
let num : number = 10
let flag : boolean = true

数组

定义

let strList: string[] = ['a', 'b', 'c']

let numList: Array<number> = [1, 2, 3]

any

let obj: any = {
    x: 0
}

obj.test()

obj.name = 'any name'

const loginFlag: boolean = obj.isSucces

编译后

let obj = {
    x: 0
};
obj.test();
obj.name = 'any name';
const loginFlag = obj.isSuccess;

运行报错:

/Users/wuhuaming/WebstormProjects/TypeScript/base02/dist/base-type.js:10
obj.test();
    ^

TypeError: obj.test is not a function
    at Object.<anonymous> (/Users/wuhuaming/WebstormProjects/TypeScript/base02/dist/base-type.js:10:5)
    at Module._compile (node:internal/modules/cjs/loader:1241:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
    at Module.load (node:internal/modules/cjs/loader:1091:32)
    at Module._load (node:internal/modules/cjs/loader:938:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:83:12)
    at node:internal/main/run_main_module:23:47

对象类型&函数

function printCoord(pt: {x: number, y: number}) {
    console.log('x坐标:' + pt.x)
    console.log('y坐标:' + pt.y)
}

printCoord({
    x: 3,
    y: 4
})


function printName(obj: {firstName: string, lastName?: string}){
    console.log('firstName: ' + obj.firstName.toLocaleLowerCase)
    console.log('lastName:' + obj.lastName?.toLocaleLowerCase)
}

printName({
    firstName: 'wuji',
    lastName: 'Zhang'
})
  • 如果参数是可选的,参数后面添加**?**
  • 在不确定字段是否是undefined的时候也可以使用**?**来安全的调用其方法

联合类型

两个或多个其他类型组成的类型

let id: number | string

表示id既可以是数值型也可以是字符串类型

function printId(id: number | string) {
    console.log(id)
}

printId(100)

printId('1024')

typeof运用

const log = console.log

function printString(s: string[] | string | number){

    if(Array.isArray(s)){
        log(s.join(' , '))
    }else if(typeof s === 'string'){
        log(s.toUpperCase())
    }else{
        log(s)
    }

}

printString(['a', 'b', 'c'])

printString('w')

printString(10)


function getFirstThree(x: number[] | string){
    return x.slice(0, 3)
}


log(getFirstThree('abcdefg'))

log(getFirstThree([1,2]))

类型别名

//
type Point = {
  x: number;
  y: number;
}

//
type Point = {x: number, y: number}
// 
type MyId = number | string
  • 类型名称一般以大写字母开头

接口

interface MyPoint {
    x: number
    y: number
}

接口之间继承

 interface Animal{
    name: string
 }

 interface Bear extends Animal {
    honey: boolean
 }

 const bear: Bear = {
     honey: true,
     name: "winie"
 }

console.log(bear.name)


console.log(bear.honey)

接口和类型别名的区别

  • 类型别名创建以后,不能在扩展字段,接口可以扩展字段

类型断言 as

const myApp = document.getElementById('myApp') as HTMLCanvasElement

const myApp1 = <HTMLCanvasElement> document.getElementById('myApp')


const asObj = ('16' as unknown) as number

文字类型

const

  • const: 声明一个只读的变量,声明后,值就不能改变

  • const必须初始化

  • const并不是变量的值不能改动,而是变量指向的内存地址所保存的数据不得改动

    const obj = {
    	age: 17
    }
    obj.age = 18;  // ok
    
    obj = {
    	age: 18
    }
    //  SyntaxError: Identifier 'obj' has already been declared
    

let

  • 不存在变量提升,let声明变量前,该变量不能使用(暂时性死区)。

  • let命令所在的代码块内有效,在块级作用域内有效

    {
    	let a = 10;
    }
    console.log(a);  // ReferenceError: a is not defined
    
  • let不允许在相同作用域中重复声明,注意是相同作用域,不同作用域有重复声明不会报错

    let a = 10;
    let a = 20;
    // Uncaught SyntaxError: Identifier 'a' has already been declared
    
    let a = 10;
    {
    	let a = 20;
    }
    // ok
    

var

  • 存在变量提升

    console.log(a); // undefined
    var a = 10;
    
    // 编译过程
    var a;
    console.log(a); // undefined
    a = 10;
  • 一个变量可多次声明,后面的声明会覆盖前面的声明
    var a = 10;
    var a = 20;
    console.log(a); // 20
    
  • 在函数中使用var声明变量的时候,该变量是局部的

    var a = 10;
    function change(){
        var a = 20;
    }
    change();
    console.log(a); // 10
    

文字类型

function printText(s: string, aligenment: 'left' | 'center' | 'right') {
    // todo
}

printText('hello', "left")
function compare(a: number, b: number): -1 | 0 | 1 {
    return a === b ? 0 : a > b ? 1 : -1
}


console.log(compare(2, 3))

console.log(compare(2, 2))

console.log(compare(2, 1))
interface Options {
    width: number
}

function config(x: Options | 'auto') {
    // todo
}

config({ width: 1080})

config('auto')

枚举

enum Direct {
    Up = 1,
    Down,
    Left,
    Right,
}


console.log(Direct.Up)
console.log(Direct.Right)

结果:

1
4

类型缩小

typeof 类型守卫

typeof str === "object" | "string" | "number" | "boolean" | "bigint" | "symbol" | "undefined" | "function"
function printAll(s: string | string[] | null){
    if(s !== null && typeof s === 'object'){
        for(const str of s){
            console.log(str)
        }
    }else if (typeof s === 'string'){
        console.log(s.toUpperCase())
    }else{
        console.log('s is null')
    }
}

printAll(['a', 'b', 'cdfgj'])

printAll('a')

printAll(null)

真值缩小

console.log(Boolean('hello'))//true

console.log(!!'hello')//true

等值缩小

in 操作符缩小

type Fish = { swim: ()=> {}}

type Bard = { fly: () => void}

// type People = { swim?: ()=> void, fly?: () => void}

function move(animal: Fish | Bard) {
    if('swim' in animal){
        return animal.swim()
    }
    return animal.fly()
}

instanceof

function printDate(str: Date | string){
    if(str instanceof Date){
        console.log(str.getDate())
    }else{
        console.log(str.toUpperCase())
    }
}

printDate(new Date())

printDate('hello word')

类型谓词

type Fish = { 
    name: string
    swim: ()=> void
}

type Bard = { 
    name: string
    fly: () => void
}

function isFish(animal: Fish | Bard): animal is Fish {
    return (animal as Fish).swim !== undefined
}

function getAnimal(num: number): Fish | Bard {
    let fish: Fish = {
        name: "sharkey",
        swim: function () {
            console.log(this.name + 'swimming')
        }
    }

    let bard: Bard = {
        name: "sparrow",
        fly: function (): void {
            console.log(this.name + 'flying')
        }
    }

    return num === 1 ? fish : bard
}


const zoo: (Fish | Bard)[] = [getAnimal(1), getAnimal(0), getAnimal(0), getAnimal(1)]

const fishList = zoo.filter(isFish)

const fishList1 = zoo.filter(isFish) as Fish[]

const fishList2 = zoo.filter((item): item is Fish => {
    if(item.name === 'frog' || item.name === 'sparrow'){
        return false
    }
    return isFish(item)
})

console.log(fishList)

console.log(fishList1)

console.log(fishList2)

结果:

[
  { name: 'sharkey', swim: [Function: swim] },
  { name: 'sharkey', swim: [Function: swim] }
]
[
  { name: 'sharkey', swim: [Function: swim] },
  { name: 'sharkey', swim: [Function: swim] }
]
[
  { name: 'sharkey', swim: [Function: swim] },
  { name: 'sharkey', swim: [Function: swim] }
]
0%