1.TypeScript安装和基础
          目录
          
        
        
      安装TypeScript
# 全局安装
npm install -g typescript
# 更新
npm update typescript -g
# 查看TypeScript版本
tsc -vTS编译成JS
hello.ts
console.log('hello typescript')tsc hello.tshello.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] }
]
