学习typescript-----基础


ts支持js中几乎所有的数据类型,还提供了额外的枚举类型

js数据类型: string、boolean、number、undefined、null、symbol和object

boolean

let bool:boolean = true

string

let str: string = 'abc'
let sayhi: string = `hi, my name is ${str}`

number

let n: number = 10
let n1: number = '0b0101'
let n2: number = '0o4567'
let n3: number = '0x34cde'
let n4: number = 'NaN'

ts中的空(void)一般用来表明没有任何返回值的函数

function abc(): void{
   console.log(123)  
}

null和undefined

null和undefined是所有类型的子类型,可以赋值给任意类型

任意值

let a:any = 'str'
a = 123
在任意值上访问任何属性都是允许的
a.abc().def.ghj()
初始化时未指定类型和未赋值,默认就会给any类型

 

类型推论

ts会在没有明确给定类型的时候,推测出一个类型。

 

联合类型

联合类型表示取值可以取限定类型中的一种

let abc: string|number
abc  = 'abc'
abc = 123

如果访问联合类型中的属性或方法,只能访问此联合类型所有类型中共有的属性或方法

对象类型-接口

ts的接口可以对类的一部分进行抽象,还可以对对象进行描述

interface Person{
  name: string
  age: number
}

let obj: Person = {
  name: 'abc',
  age: 10
}

接口一般建议首字母大写, 使用时所定义的变量必须和接口规定的变量保持一致, 多属性或者少属性都是不允许的。

 可选属性

interface Person{
  name: string
  age?: number
}
但仍然不允许添加未定义的属性

 任意属性

interface Person {
  name: string
  age?: number
  [propName: string]: any
}
[propName: string]定义了任意属性取string类型的值
注意: 一旦定义了任意属性,确定属性和可选属性的类型都必须是它的类型的子级
一个接口中只能有一个任意类型

 只读属性

interface Person{
  readonly name: string
}

数组类型

在ts中,定义数组的方式有很多种

1,类型+方括号
let arr: number[] = [1,2,3,4,5]
数组的项中不允许出现其他的类型
数组的方法也会进行类型的限制
可以使用any来允许数组中出现任意类型
let arr: any[] = [1, 'ab', {a: 1}]

2,数组泛型
let arr: Array = [1,2,3,4,5]

3,用接口表示
interface Array{
  [index: number]: number
}
 类数组:
 Interface Arguments {
   [index: number]: number
   length: number
   callee: Function
 }
// 注: 这里为什么任意类型为number, callee却是Function, Function并不是number的子类型。
 答:因为index指定的是number类型, callee是string, 不受index的number类型的影响

函数类型

函数是js中的一等公民

 函数表达式

function abc (x: string, y: number): void {
  console.log(x, y)
}
调用时输入多余或者少的参数是不允许的。

 函数声明

const fn: (x: number, y:string) => void = function (x:number, y: string): void {
  console.log(x, y)
}
请注意 ts类型定义中的 => 和 es6 箭头函数的区别
ts中 =>用来表示函数的定义, 左边是输入类型,右边是输出类型

也可以用接口的方式来定义函数类型
interface Fn {
(x: number, y: string): boolean
}
let myFn: Fn
myFn = function (x: number, y: string): boolean(){ return false }

 可选参数

 可选参数与接口中的可选属性类似, 用?:来表示,需要注意的是,可选参数必须是在必须参数的后面,也就是说可选参数后面不允许出现必须参数了

 参数默认值

function fn(x:string = 'abc', y:number): void {
  console.log(x, y)
}
ts会将添加了默认值的参数识别为可选参数,
此时可选参数就不用必须放在必须参数后面了。

 reset参数

 ...items: any[], reset参数必须是最后一个参数

 重载

 重载允许一个函数接受不同数量或类型的参数时,作出不同的处理

 类型断言

值 as 类型

 类型断言的用途

  1,将一个联合类型断言为其中一个类型

    在ts中,如果不确定一个联合类型的变量到底是什么类型时,只能访问此联合类型所有类型中共有的方法或属性。

    而有时候我们需要在还不确定类型的时候,就访问其中一个特有的属性或者方法,此时就需要用到类型断言

interface Fish{
  name: string,
  swim(): void
}

interface Cat{
  name: string,
  run(): void
}

function goSwim (animal: Fish | Cat) {
  if (animal.swim) { return true }  // 报错  Cat上没有swim
  return false
}

function goSwim (animal: Fish|Cat) {
  if ((animal as Fish).swim) return true // 正确
  return false
}

      断言只能欺骗ts编译器,并不能避免运行时的错误。

   2,将一个父类断言为更加具体的子类

class ApiError extends Error {
   code:number = 0
}
class HttpError extends Error {
   statusCode: number = 200
}
function isApiError (error: Error) {
  if (typeof (error as ApiError).code === 'number') {
      return true
  }
   return false
}

   3,将任何类型断言为any

window.abc = 1 // 报错 window上没有abc

(window as any).abc = 1 // 正确,  在any类型上访问任何属性都可以

  4,将any断言为一个具体的类型

function getData(key: string): any {
  return (window as any)[key]
}

interface Cat {
  name: string
  run(): void
}
let tom = getData('tom') as Cat
tom.run()
tom.name

 类型断言的限制

  由上所知:1,联合类型可用被断言为其中一个类型, 2,父类可以被断言为子类 、3,任何类型都可以被断言为any、4,any可以被断言为任何类型

类型断言的限制: 如果A兼容B,则A可以断言为B,B也可以断言为A

 双重断言

  既然任何类型可以断言为any, any可以断言为任何类型

那么可以用as any as来将一个类型断言为任何其他类型
interface A {
 name: string
}
interface B {
 age: number
}
function test(testA: A) {
  return (testA as any as B)
}
一般使用到双重断言,十有八九是错误的,会导致运行时报错

 类型断言 vs 类型转换

function toBoolean (p: any): boolean {
  return p as boolean
}
toBoolean(111) // 返回的还是 111
这样做可以通过编译,但是并没有什么用
所以类型断言并不会真的影响到变量的类型

 类型断言 vs 类型声明

类型声明比类型断言更加的严格。
a 断言为 b : 只需要满足a兼容b或者b兼容a
a 声明为 b :只有b兼容a才可以

内置对象

1,ECMAScript的内置对象
  let b:Boolean = new Boolean(0)
  let e: Error = new Error('error')
  let d: Date = new Date()
  let r: RegExp = /\d/g
2,BOM和DOM的内置对象
  let body: HTMLElement = document.body
  let divs: NodeList = document.querySelectorAll('div')
  document.addEventListener('click', function(e: MouseEvent){})
3, 核心库的定义
 Math.random()