TS系列(1):TS是什么?如何使用?
TS系列(2):类型声明、类型推断和类型总览
TS系列(3):常用类型(详细)
TS系列(4):常用类型之类、抽象类和接口
话接上回,什么是泛型?什么是类型声明文件?
八、泛型
泛型允许我们在定义函数、类或接口时,使用类型参数来表示未指定的类型,这些参数在具体使用时,才被指定具体的类型,泛型能让同一段代码适用于多种类型,同时仍然保持类型的安全性。
举例来说:如下代码中<T>
就是泛型,不一定叫T
,设置泛型后即可在函数中使用T
来表示该类型:
泛型函数
function logData<T>(data: T): T {
console.log(data)
return data
}
logData(10) // 不指定泛型,TS可以自动对类型进行推断
logData<number>(100) // 指定泛型
logData<string>('hello') // 指定泛型
泛型数组
// 方式1
function fn1<T>(arr: T[]): T[] {
console.log(arr.length)
return arr
}
// 方式2
function fn2<T>(arr: Array<T>): Array<T> {
console.log(arr.length)
return arr
}
多个泛型
function logData<T, K>(data1: T, data2: K): T | K {
console.log(data1, data2)
return Date.now() % 2 ? data1 : data2
}
logData(100, 'hello') // 不指定泛型,TS会自动对类型进行推断
logData<number, string>(100, 'hello') // 指定泛型
logData<string, boolean>('hello', false) // 指定泛型
泛型接口
// 示例1
interface PersonInterface<T> {
name: string,
age: number,
extraInfo: T
}
let p1: PersonInterface<string>
let p2: PersonInterface<number>
p1 = {
name: '张三',
age: 18,
extraInfo: '厉害人物'
}
p2 = {
name: '李四',
age: 18,
extraInfo: 250
}
// 示例2
interface Info<T> {
like: T
}
let zhangsan: Info<string> = {
like: '篮球'
}
let lisi: Info<string[]> = {
like: ['篮球']
}
// 示例3
interface fn<T> {
(a1: T, a2: T): T[]
}
let f1: fn<string> = function(a, b) {
return [a, b]
}
let f2: fn<number> = function(a, b) {
return [a, b]
}
console.log(f1('1', '2')) // ['1', '2']
console.log(f2(1, 2)) // [1, 2]
泛型约束(指定泛型类型)
// 示例1
interface PersonInterface {
name: string,
age: number
}
function logPerson<T extends PersonInterface>(info: T): void {
console.log(`我叫${info.name},今年${info.age}岁了`)
}
logPerson({ name: '张三', age: 18 })
// 示例2
function fn<T extends string|any[]>(a: T):number {
return a.length
}
fn('hello') // 正常
fn([1, 2, 3]) // 正常
fn(123) // Argument of type 'number' is not assignable to parameter of type 'string | any[]'
泛型类
class Person<T> {
constructor(
public name: string,
public age: number,
public extraInfo: T
) { }
speak() {
console.log(`我叫${this.name},今年${this.age}岁了`)
console.log(this.extraInfo)
}
}
const p1 = new Person<string>('小明', 10, '很聪明')
type JobInfo = {
title: string
company: string
}
const p2 = new Person<JobInfo>('张三', 30, { title: '总经理', company: '华夏科技公司' })
keyof
interface Info {
name: string,
age: number
}
let zhangsan: Info = {
name: 'zhangsan',
age: 10
}
getInfoValue(zhangsan, 'name')
// 示例1
function getInfoValue(info: Info, key: string): void {
// 这里会报错,因为传入的 key 可能不是 Info 的属性
console.log(info[key])
}
// 示例2
function getInfoValue(info: Info, key: keyof Info): void {
console.log(info[key])
}
// 示例3
function getInfoValue<T extends keyof Info>(info: Info, key: T): Info[T] {
return info[key]
}
九、类型声明文件
类型声明文件是 TypeScript 中的一种特殊文件,通常以.d.ts
作为扩展名。它的主要作用是为现有的 JavaScript 代码提供类型信息,使得 TypeScript 能够在使用这些 JavaScript 库或模块时进行类型检查和提示。
demo.js
export function add(a, b) {
return a + b
}
export function mul(a, b) {
return a * b
}
demo.d.ts
declare function add(a: number, b: number): number
declare function mul(a: number, b: number): number
export { add, mul }
example.ts
import { add, mul } from './demo.js'
const x = add(2, 3) // x 类型为 number
const y = mul(4, 5) // y 类型为 number
console.log(x, y)
好了,分享结束,谢谢点赞,下期再见。