Bootstrap

typeScript学习

执行命令

  • npm i -s typescript
  • npx tsc --init 生成tsconfig.json文件
  • npx tsc xxx.ts
  • npx tsc --watch
    自动编译,在报错时不进行自动编译
  • npx tsc --noEmitOnError --watch
  • node xx.js 执行对应文件

tsconfig.json

  1. 严格模式
  • “strict”: true
  • “noImplicitAny”: true
  • “strictNullChecks”: true
  1. 降级
  • “target”: “es2016”
  1. 输出的js文件
  • “outDir”: “./dist”
  1. ts所在文件
  • “rootDir”: “./src”,

类型

基元类型:string、number、boolean

let str:string= 'hello typescript'
let num:number = 100
let bool:boolean = true

array

let arr:number[] = [1,2,3]
// arr = ['a']
let arr2:Array<number> = [1,2,3]
// arr2=['a']

any

  • 不希望某个特定值导致类型检查错误 可以用任何类型的值
let obj:any={
   
  x:0
}
// let obj={
   
//   x:0
// }
// obj.foo()
// obj()
// obj.bar = 100
// obj = 'hello'
// const n:number = obj

变量上的类型注释

// let myName:string = 'Felixlu'
// int x = 0

let myName = 'Felixlu'
// myName = 100

函数

function greet(name:string){
   
  console.log("Hello," + name.toUpperCase() + "!!")
}
greet('aa')
function getFavoriteNumber():number{
   
  return 26
}

const names = ['小前','小封','小圆']
names.forEach(function(s) {
   
  console.log(s.toUpperCase())
})
names.forEach((s)=> {
   
  console.log(s.toUpperCase)
})

对象类型

function printCoord(pt:{
   x:number;y:number}){
   
  console.log("x:" + pt.x)
  console.log("y:" + pt.y)
}
printCoord({
   x:3, y:7})

function printName(obj: {
   first:string, last?: string}){
   
  // console.log(obj.last?.toUpperCase())
  // if(obj.last != undefined){
   
  //   console.log(obj.last.toLowerCase())
  // }
  // ?解决last是undefined的问题
  console.log(obj.last?.toUpperCase())
}
// printName({
   
//   first:'Felix'
// })
// printName({
   
//   first:'Felix',
//   last:'Lu'
// })
printName({
   
  first:'Felix',
  last:undefined
})

联合类型union

  • let id: number | string
  • 两个或多个其他类型组成的类型
function printId7(id:number | string){
   
  // console.log('Your ID is:' +id)
  // console.log(id.toUpperCase())
  if(typeof id === 'string'){
   
    console.log(id.toUpperCase())
  }else{
   
    console.log(id)
  }
}

printId7(101)
printId7('202')
// printId7(true)

function welcomPeople(x:string[] | string){
   
  if(Array.isArray(x)){
   
    console.log('Hello,' + x.join('and'))
  }else{
   
    console.log('Welcome lone traveler' + x)
  }
}

welcomPeople('A')
welcomPeople(['a','b'])

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

console.log(getFirstThree('abcdefg'))
console.log(getFirstThree([2,3,4,5,6]))

类型别名

  • 给类型定义一个名字,用这个名字来代替定义的类型
type Point = {
   
  x:number
  y:number
}
function printCoord8(pt:Point) {
   

}
printCoord8({
   x:100,y:200})

type ID = number | string
function printId8(id:ID){
   

}
printId8(100)
printId8('10')

type UserInputSanitizedString = string
function sanitizedInput(str:string): UserInputSanitizedString {
   
  return str.slice(0,2)
}
let userInput = sanitizedInput('hello')
console.log(userInput)
userInput = 'new Input'

接口

一种结构类型,定义对象类型的另外一种方式 用关键字interface来定义

interface Point9{
   
  x:number;
  y:number;
}
function printCoord9(pt:Point9){
   
  console.log("坐标x的值是:"+pt.x)
  console.log("坐标y的值是:"+pt.y)
}
printCoord9({
   x:100,y:100})

// 扩展接口
/* interface Animal{
  name:string
}
interface Bear extends Animal{
  honey:boolean
}
const bear:Bear = {
  name:'winie',
  honey: true
}
console.log(bear.name)
console.log(bear.honey) */

/* type Animal = {
  name:string
}
type Bear = Animal & {
  honey:boolean
}
const bear:Bear = {
  name:'winnie',
  honey:true
} */

// 向现有的类型添加字段
/* interface MyWindow {
  count:number
}
interface MyWindow {
  title:string
}
const w: MyWindow = {
  title:'hello ts',
  count:100
} */

// 类型type创建后不能更改, interface可新增
/* type MyWindow = {
  title:string
}
type MyWindow = {
  count:string
} */

类型断言

  • 指定一个更具体的类型 类型断言由编译器来删除
  1. const myCanvas = document.getElementById(“main_canvas”) as HTMLCanvasElement
  2. const myCanvas = document.getElementById(“main_canvas”)
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement
const myCanvas2 = <HTMLCanvasElement>document.getElementById("main_canvas")

const x = ('hello' as any) as number
const y = ('hello' as unknown) as number

文字类型

let b2:false = false

const obj11 = {
   
  count:0
}
if(true){
   
  obj11.count = 1
}

function handleRequest(url:string, method: 'GET'|'POST'|'GUESS'){
   }
/* const req = {
  url:'https://example.com',
  method:'GET' // 1 method:'GET' as 'GET'
}
// handleRequest(req.url, req.method) // Argument of type 'string' is not assignable to parameter of type '"GET" | "POST" | "GUESS"'
handleRequest(req.url, req.method as 'GET') // 2 */
const req = {
   
  url:'https://example.com',
  method:'GET'
} as const  // 3
// handleRequest(req.url, req.method) // Argument of type 'string' is not assignable to parameter of type '"GET" | "POST" | "GUESS"'
handleRequest(req.url, req.method) // 2

null 和 undefined类型

null 不存在
undefined 未初始化的值

let x12:undefined = undefined
let y12:null = null
// let z12:string = undefined // Type 'undefined' is not assignable to type 'string'.  // 可将tsconfig.josn文件"strictNullChecks"改为false,就可行

function doSomething(x:string | null){
   
  if(x=== null){
   
    // 做一些事情
  }else {
   
    console.log('Hello,' + x.toUpperCase())
  }
}

function liveDangerously(x?:number | null){
   
  // !断言为你能肯定这个值不是null或者undefined
  console.log(x!.toFixed())
}

枚举

enum Direction{
   
  Up = 1,
  Down,
  Left,
  Right,
}
console.log(Direction.Up) // 1

不太常用的原语

bigint 非常大的整数
symbol 全局唯一引用

// BigInt literals are not available when targeting lower than ES2020. 修改"target": "es2020",
const oneHundred: bigint = BigInt(100)
const anotherHundred: bigint = 100n

const firstName = Symbol("name")
const secondName = Symbol("name")

// This comparison appears to be unintentional because the types 'typeof firstName' and 'typeof secondName' have no overlap.
// if(firstName === secondName){
   
//   console.log('ok')
// }

缩小

类型缩小

宽类型转为窄类型过程,常用于处理联合类型变量的场景

function padLeft(padding:number | string, input: string): string {
   
  <!-- throw new Error("尚未实现!") -->
  return new Array(padding + 1).join(" ") + input
}
function padLeft(padding:number | string, input: string){
   
  if(typeof padding === "number"){
   
    return new Array(padding + 1).join(" ") + input
  }
  return padding + input
}
function printAll(strs:string | string[] | null){
   
  // 'strs' is possibly 'null' 因为typeof null == object
  if(typeof strs === 'object'){
   
    // for(const s of strs){
   
    //   console.log(s)
    // }
  }else if(typeof strs === 'string'){
   
    console.log(strs)
  } else {
   
    // ...
  }
}

typeof 类型守卫

typeof strs === “object” // “string”、“number”,“bigint”,“boolean”,“symbol”,“undefined”,“function”

function printAll2(strs:string | string[] | null){
   
  // 'strs' is possibly 'null' 因为typeof null == object
  /* if(strs && typeof strs === 'object'){
    for(const s of strs){
      console.log(s)
    }
  }else if(typeof strs === 'string'){
    console.log(strs)
  } else {
    // ...
  } */
  if(strs){
   
    if(typeof strs === 'object'){
   
      for(const s of strs){
   
        console.log(s)
      }
    }else if(typeof strs === 'string'){
   
      console.log(strs)
    } else {
   
      // ...
    }
  }
}

function multiplyAll(
  values:number[] | undefined,
  factor:number
){
   
  if(!values){
   
    return values
  }else{
   
    return values.map((x) => {
   
      return x*factor
    })
  }
}
console.log(multiplyAll([3,4],2))
console.log(multiplyAll(undefined,2))
multiplyAll([3,4],2)

真值缩小

条件、&&、||、if语句、布尔否定( !)
function getUsersOnlineMessage (numUsersOnline:number){

if(numUsersOnline){
return 现在共有 ${numUsersOnline} 人在线!
}
return “现在没有人在线. 😦”
}

Boolean(“hello”) // type:boolean,value:true
!!“world” // type:true, value:true

等值缩小

=== , !==, ==, !=

function example3(x:string | number, y: string | boolean){
   
  // x.toUpp
;