typescript详解
邵预鸿 Lv5

类型断言

1
2
3
const ele = document.querySelector('#canvas') as HTMLCanvasElement

const ele = <HTMLCanvasElement>document.querySelector('#canvas')

In

1
2
3
4
5
6
7
8
type Fish = { swim: ()=>void }
type Bird = { fly: ()=>void }
function func(method: fish|Bird){
if('swim' in Fish){
Fish.swim()
}
return Bird.fly()
}

instansof

1
2
3
4
5
6
7
 function func(x: Date | string){
if(x instanceof Date){
console.log(x.getTime())
}else{
console.log('string')
}
}

带属性的函数(函数签名)

1
2
3
4
5
6
7
8
9
type IFunc = {
count: number,
(value: number): string
}

const getCount: IFunc = value=>{
return '111'
}
getCount.count = 1;

泛型

1
2
3
4
function doSomething<T>(a: T):T{
//检测T的类型,并返回T类型
}
doSomething('hello')

多种泛型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function doSomething<T extends {length:number},B>(a: T, b: T):T // 公共属性条件约束

function doSomething<T extends string|number,B>(a: T, b: B):B{
//检测T的类型, B的类型, 返回B的类型
if(typeof b === 'string'){
return b+'123' as B;
}
if(typeof b === 'number'){
return b*2 as B;
}
return b;
}

doSomething('hello', 123)

泛型强制类型转换

1
2
3
4
5
6
7
8
function doSomething<T>(a: T, b: T):T{
//检测T的类型,并返回T类型
return a.concat(b)
}
doSomething(['hello'], [123]) // 报错, 第一个推断为string, 参数B只能是string

doSomething<string | number >(['hello'], [123]) // 非必要,强制转换,可以正常运行

函数重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function getDate():Date;
function getDate(y:number, m: number, d: number): Date;
function getDate(now: number): Date;

// 实现
function getDate(yOrNow?: number, m?: number, d?: number):Date{
if(yOrNow === undefined){
}else if(yOrNow){
}else if(m && d){
}
}

getDate()
getDate(2013,3,2)
getDate(Date.now())

getDate(2013, 3); // XXXXX

https://typescript.bootcss.com/functions.html

1
2
3
4
5
function getDate(x: string): string;
function getDate(x: number): number;

function getDate(x: string| number): string| number{
}

返回值

ts中return; 推断返回的是void; 而js中return; 返回undefined

readOnly

在 TypeScript 中,as const 是一种 常量断言(Const Assertion) ,它主要作用是将表达式类型推断为 最具体的字面量类型 ,并确保其属性不可变。以下是它的核心用途和效果:

1
2
3
4
5
// 普通声明
let a = "hello"; // 类型: string

// 使用 as const
let b = "hello" as const; // 类型: "hello" (字面量类型)
1
2
3
4
5
6
7
8
9
const obj = {
name: "Alice",
age: 30,
hobbies: ["coding", "reading"]
} as const;

// 所有属性不可修改
obj.name = "Bob"; // ❌ 错误: 只读属性
obj.hobbies.push("music"); // ❌ 错误: 只读数组
1
2
3
4
5
// 普通数组
const arr1 = [1, "a"]; // 类型: (string | number)[]

// 使用 as const
const arr2 = [1, "a"] as const; // 类型: readonly [1, "a"] (元组)
1
2
3
4
5
6
7
8
9
function setStatus<T extends "idle" | "loading">(status: T) { ... }

// 普通变量会被推断为 string,导致错误
let status = "idle";
setStatus(status); // ❌ 错误: string 不能赋值给字面量类型

// 使用 as const 解决
let status = "idle" as const;
setStatus(status); // ✅ 正确

函数参数解构

1
2
3
4
5
6
7
8
9
 function getTime({year,month,date}: {year: number, month: number, date: number}): string{
return `${year}-${month}-${date}`
}

getTime({
year: 2024,
month: 2,
date: 3
})

索引签名

1
2
3
4
5
interface NumberDictionary {
[index: string]: number | string;
length: number; // 可以,length是number类型
name: boolean // 错误,`name`的类型与索引类型返回值的类型不匹配
}
1
2
3
4
5
interface ReadonlyStringArray {
readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // error!

多重继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface Shape {
color: string;
}

interface PenStroke {
penWidth: number;
}

interface Square extends Shape, PenStroke {
sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

unknown

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface Box{
content: unknown
}

const data: Box = {
content: 'hello'
}

data.content.split(','); // 报错

// 处理办法1
if(typeof data.content === 'string'){
data.content.split(',')
}

// 处理办法2
(data.content as string).split(',')

可值参泛型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface Shao<T>{
name: string;
age: number;
school: T
}

interface SchoolInfo {
grade: number,
order: number,
name: string
}
const info: Shao<SchoolInfo> ={
name: 'xiaohong',
age: 22,
school: {
grade: 1,
order: 100,
name: '重庆大学'
}
}
const info2: Shao<null> ={
name: 'xiaohong',
age: 22,
school: null
}

多个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface Shao<T,P>{
name: P;
age: number;
school: T
}

interface SchoolInfo {
grade: number,
order: number,
name: string
}
const info: Shao<SchoolInfo, string> ={
name: 'xiaohong',
age: 22,
school: {
grade: 1,
order: 100,
name: '重庆大学'
}
}
const info2: Shao<null, number> ={
name: 0,
age: 22,
school: null
}

套娃的泛型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
type Shao<T> = {
name: string;
age: number;
school: T
}
type Res<T> = {
code: number,
message: string,
data: T
}
type SchoolInfo = {
grade: number,
order: number,
name: string
}

const result: Res<Shao<SchoolInfo>> = {
code: 200,
message: '操作成功',
data: {
name: 'xiaohong',
age: 22,
school: {
grade: 1,
order: 100,
name: '重庆大学'
}
}

}

类型对象约束

1
2
3
4
5
6
7
8
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}

let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, "a"); // okay
getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.

keyof

1
2
3
4
5
6
7
8
9
10
type obj1 = {
x: number;
y: string
}
interface Box {
x: unknown
}

const p1: keyof obj1 = 'x'; // 等价于 const p1: 'x'| 'y
const p2: keyof Box = 'x';

ReturnType <Function>

通过returnType,返回函数返回值的类型

1
2
3
4
5
6
7
8
9
10
function getXy():{x: number, y: number}{
return {
x: 100,
y: 100
}
}
const pos: ReturnType<typeof getXy> = {
x: 0,
y: 0
}

索引类型

1
2
3
4
5
6
7
8
9
type MyInfo = {
name: string;
age: number;
sex: boolean
}

const d1: MyInfo['name'] = 'xiaoming'; // string
const d2: MyInfo['name' | 'age'] = 222; // string | number
const d3: MyInfo[keyof MyInfo] = 222; // string | number | boolean

泛型条件约束

1
2
3
4
5
6
7
8
9
10
11
12
13
type NameOrId<T extends number|string> = T extends number ? {age: number} : {id: string} 

function create<T extends number | string>(arg: T):NameOrId(T){
}


type Message<T> = T extends {message: unkown} ? T['message'] : never;
interface Email {
message: string
}
type MessageContent= Message<Email> // string类型
type MessageContent2 = Message<RegExp> // never

1
2
3
4
5
type GetReturnType<T> = <T extends (..args: string[])=>infer R ? R : never;

type func1 = GetReturnType(([])=>number); // number
type func2 = GetReturnType(([])=>string); // string
type func1 = GetReturnType(string); // never
1
2
3
type Arr<T> = T extends {length: number} ? T[] : number;

type Arr1 = Arr<string | number>; // string[] | string
  • 本文标题:typescript详解
  • 本文作者:邵预鸿
  • 创建时间:2025-07-17 09:54:27
  • 本文链接:/images/logo.jpg2025/07/17/typescript详解/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!