# 基本使用

# 基础类型和变量声明

  • boolean

  • number

  • string

  • void /null undefined

  • null

  • undefined

  • symbol

  • bigint

  • any

  • unknown

  • never // never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型

# boolean

const isNumber: boolean = true

# number

const count: number = 1

# string

const name: string = '12'

# void

function hello(): void {
  console.log('hello typescript')
}

# null 和 undefined

const u: undefined = undefined // undefined
const n: null = null // null

# any

let number: any = 'one'
number = 1 // 1
const me: any = 'axuebin'
console.log(me.name) // undefined 不会报错

# 类型推断

如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。

let myFavoriteNumber = 'seven'
myFavoriteNumber = 7

// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'

let myFavoriteNumber //any
myFavoriteNumber = 'seven'
myFavoriteNumber = 7
// 编辑器不会有任何提示

# 联合类型

联合类型(Union Types)表示取值可以为多种类型中的一种。

  • 联合类型使用 | 分隔每个类型。
let myFavoriteNumber: string | number
myFavoriteNumber = 'seven'
myFavoriteNumber = 7
  • 当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
function getLength(something: string | number): number {
  return something.length
}

// index.ts(2,22): error TS2339: Property 'length' does not exist on type 'string | number'.
//   Property 'length' does not exist on type 'number'.
  • 联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型
let myFavoriteNumber: string | number
myFavoriteNumber = 'seven'
console.log(myFavoriteNumber.length) // 5
myFavoriteNumber = 7
console.log(myFavoriteNumber.length) // 编译时报错

// index.ts(5,30): error TS2339: Property 'length' does not exist on type 'number'.

# 对象的类型 -- 接口

在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。

TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述 赋值的时候,变量的形状必须和接口的形状保持一致。不能多一个属性 不能少一个属性

interface Person {
  name: string
  age: number
}

let tom: Person = {
  name: 'Tom',
  age: 25
}

怎么可以形状不一样呢?

# 可选属性

interface Person {
  name: string
  age?: number
}

let tom: Person = {
  name: 'Tom'
}

多一些属性也是不允许的

# 任意属性

一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:

# 只读属性

有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性

# 数组的类型

# 最简单的方法是使用「类型 + 方括号」来表示数组

const me: string[] = ['axuebin', '27'] // 定义一个都是 string 的数组
const counts: number[] = [1, 2, 3, 4] // 定义一个都是 number 的数组
// error
const me: string[] = ['axuebin', 27] // Type 'number' is not assignable to type 'string'.
counts.push('5') // Argument of type '"5"' is not assignable to parameter of type 'number'.

# 还有一种方式是使用泛型

const data: Array<number> = [1, 2, 3, 4]

# 类数组 (了解)

事实上常用的类数组都有自己的接口定义,如 IArguments, NodeList, HTMLCollection 等

function sum() {
  let args: {
    [index: number]: number
    length: number
    callee: Function
  } = arguments
}

# 函数的类型

在 JavaScript 中,有两种常见的定义函数的方式——函数声明(Function Declaration)和函数表达式(Function Expression)

# 函数声明

// 函数声明(Function Declaration)//js
function sum(x, y) {
  return x + y
}
//ts
function(x:number,y:number):number{
  return x+y
}

TIP

输入多余的(或者少于要求的)参数 在 js 中输入少了为 undefined 输入多了直接忽略

# 函数表达式

const sum = function(x, y) {
  return x + y
}

模仿上面的写法 👆 可能会写

const sum = function(x: number, y: number): number {
  return x + y
}

但是只定义了右边 没有定义左边 左边是自动推导出来的 如果手动添加就要想下面这样

const sum: (x: number, y: number) => number = function(
  x: number,
  y: number
): number {
  return x + y
}

# 用接口定义函数的形状

interface ISum {
  (x: number, y: number): number
}

const sum: ISum = (x, y) => x + y

# 可选参数 参数可以传可以不传 可选参数后面不允许再出现必需参数

function buildName(firstName: string, lastName?: string) {
  if (lastName) {
    return firstName + ' ' + lastName
  } else {
    return firstName
  }
}
let tomcat = buildName('Tom', 'Cat')
let tom = buildName('Tom')

# 默认参数

function buildName(firstName: string, lastName: string = 'Cat') {
  return firstName + ' ' + lastName
}
let tomcat = buildName('Tom', 'Cat')
let tom = buildName('Tom')

# 剩余参数

function push(array: number[], ...items: number[]) {
  items.forEach(function(item) {
    array.push(item)
  })
}

let a: number[] = []
push(a, 1, 2, 3)

# 重载

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

比如,我们需要实现一个函数 reverse,输入数字 123 的时候,输出反转的数字 321,输入字符串 'hello' 的时候,输出反转的字符串 'olleh'。

# 类型断言

类型断言(Type Assertion)可以用来手动指定一个值的类型。 语法: 值 as 类型 / <类型>值

总结

  • 联合类型可以被断言为其中一个类型
  • 父类可以被断言为子类
  • 任何类型都可以被断言为 any
  • any 可以被断言为任何类型 详细用法 (opens new window)

    TIP

    类型断言只能够「欺骗」TypeScript 编译器,无法避免运行时的错误,反而滥用类型断言可能会导致运行时错误

# 声明文件

当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能

  • declare var 声明全局变量
  • declare function 声明全局方法
  • declare class 声明全局类
  • declare enum 声明全局枚举类型
  • declare namespace 声明(含有子属性的)全局对象
  • interface 和 type 声明全局类型
  • export 导出变量
  • export namespace 导出(含有子属性的)对象
  • export default ES6 默认导出
  • export = commonjs 导出模块
  • export as namespace UMD 库声明全局变量
  • declare global 扩展全局变量
  • declare module 扩展模块
  • /// <reference /> 三斜线指令

# 声明语句

小程序中 wx. 未定义怎么解决 不知道类型怎么解决?

# 声明文件

通常我们会把声明语句放到一个单独的文件(jQuery.d.ts)中,这就是声明文

# 第三方声明文件

可以在这个页面 (opens new window)搜索你需要的声明文件

# 为第三方库提供声明文件

https://ts.xcatliu.com/basics/declaration-files.html#%E4%B9%A6%E5%86%99%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6

# 内置对象

# ECMAScript 的内置对象

Boolean、Error、Date、RegExp 等

# DOM 和 BOM 的内置对象

Document、HTMLElement、Event、NodeList 等

# TypeScript 核心库的定义文件

TypeScript 核心库的定义文件中定义了所有浏览器环境需要用到的类型,并且是预置在 TypeScript 中的 常用的方法可以直接提示出参入参

上次更新: 12/18/2021, 11:31:42 PM