你好,我是沐爸,欢迎点赞、收藏、评论和关注。
接着前两天的继续分享,今天说下函数,包括为函数定义类型、推断类型、可选参数和默认参数、剩余参数、参数解构、参数为接口或类型别名、返回void类型、重载。
十、函数
为函数定义类型
为函数参数和返回值指定类型。
function add(x: number, y: number): number {
return x + y
}
let myAdd = function(x: number, y: number): number {
return x + y;
}
推断类型
如果函数省略返回值类型,TS 会根据语句自动推断出返回值类型。
function add(x: number, y: number) {
return x + y
}
const result = add(1, 2)
console.log(result.length) // Property 'length' does not exist on type 'number'
可选参数和默认参数
默认情况下,函数调用时,传入的参数类型和个数必须和函数定义时一致。TS 可通过?
实现可选参数功能,未传递参数时,变量的值为undefined
。
function fullName(firstName: string, lastName?: string) {
if (lastName) {
return firstName + ' ' + lastName
} else {
return firstName
}
}
let result1 = fullName('Bob') // 正常
let result2 = fullName('Bob', 'Adams') // 正常
let result3 = fullName('Bob', 'Adams', 'Sr.') // Expected 1-2 arguments, but got 3
在 TS 中,我们也可以为参数指定默认值,在没有传递参数或参数的值为undefined
时生效。
function fullName(firstName: string, lastName = 'Smith') {
return firstName + ' ' + lastName
}
let result1 = fullName('Bob') // 'Bob Smith'
let result2 = fullName('Bob', undefined) // 'Bob Smith'
let result4 = fullName('Bob', 'Adams') // 'Bob Adams'
函数的默认参数不必放在参数的末尾,如果要让默认值生效,需明确传入undefined
。
function fullName(firstName= 'Bob', lastName: string) {
return firstName + ' ' + lastName
}
let result1 = fullName('Smith') // Expected 2 arguments, but got 1
let result2 = fullName(undefined, 'Smith') // 正常
let result4 = fullName('John', 'Smith') // 正常
剩余参数
如果你不知道传递了多少个参数,可以使用剩余参数。
示例1:
function fullName(firstName: string, ...restOfName: string[]) {
return firstName + ' ' + restOfName.join(' ')
}
const result = fullName('Joseph', 'Samuel', 'Lucas', 'MacKinzie')
console.log(result) // Joseph Samuel Lucas MacKinzie
示例2:
function multiply(n: number, ...m: number[]) {
return m.map((x) => n * x)
}
const result = multiply(10, 1, 2, 3, 4)
console.log(result) // [10, 20, 30, 40]
参数解构
TS 中一样可以使用解构赋值,但需要为解构的参数指定类型,否则提示含有隐式 any
。
function sum({ a, b, c }: { a: number, b: number, c: number }) {
console.log(a + b + c)
}
sum({
a: 10,
b: 3,
c: 9
})
使用接口和类型别名改写:
type ABC = {
a: number,
b: number,
c: number
}
function sum({ a, b, c }: ABC) {
console.log(a + b + c)
}
sum({
a: 10,
b: 3,
c: 9
})
interface ABC {
a: number,
b: number,
c: number
}
function sum({ a, b, c }: ABC) {
console.log(a + b + c)
}
sum({
a: 10,
b: 3,
c: 9
})
参数为接口或类型别名
函数的参数除了可直接定义类型,也可以是接口和类型别名。
接口:
interface Person {
firstName: string
lastName: string
}
function greet(person: Person) {
console.log('Hello, ' + person.firstName + ' ' + person.lastName)
}
greet({
firstName: 'Bob',
lastName: 'Smith'
})
类型别名:
type Person = {
firstName: string
lastName: string
}
function greet(person: Person) {
console.log('Hello, ' + person.firstName + ' ' + person.lastName)
}
greet({
firstName: 'Bob',
lastName: 'Smith'
})
返回 void 类型
函数声明和函数表达式在返回 void
类型时,会有所不同:
// 函数声明
function fn1(): void {
return 100 // Type 'number' is not assignable to type 'void'
}
// 函数表达式
type voidFn = () => void
// 箭头函数
const fn2: voidFn = () => 100
// 普通函数
const fn3: voidFn = function() {
return 100
}
console.log(fn2()) // 100
console.log(fn3()) // 100
注意,函数返回void
类型时,不能根据返回值判断,进行其他操作!!
function fn1(): void {
return
}
type voidFn = () => void
const fn2: voidFn = () => 100
const fn3: voidFn = function() {
return 100
}
// 以下操作都会报错:An expression of type 'void' cannot be tested for truthiness.
if (fn1()) {
console.log('fn1')
}
if (fn2()) {
console.log('fn2')
}
if (fn3()) {
console.log('fn3')
}
重载
在 TS 中,函数重载是一种允许为同一个函数名定义多个不同函数签名的特性。实现重载需要两个步骤:
- 声明多个函数签名
- 实现函数体
示例1:
// 函数签名1
function makeDate(timestamp: number): Date
// 函数签名2
function makeDate(m: number, d: number, y: number): Date
// 实现函数体
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
if (d !== undefined && y !== undefined) {
return new Date(y, mOrTimestamp, d)
} else {
return new Date(mOrTimestamp)
}
}
const d1 = makeDate(1727620102980) // 正常
const d2 = makeDate(9, 29, 2024) // 正常
const d3 = makeDate(1727620102980, 9) // 只存在1个或3个参数的情况,不存在2个参数的情况
示例2:
function fn(x: boolean): void
function fn(x: string): void
function fn(x: boolean | string) {
console.log(x)
}
fn(false)
fn('hello')
fn(100) // 参数不合法
示例3:
function fn(x: string): string
function fn(x: boolean): boolean
function fn(x: string | boolean): string | boolean {
return x
}
fn(false)
fn('hello')
fn(100) // 参数不合法
示例4:
function len(s: string): number
function len(arr: any[]): number
function len(x: any) {
return x.length
}
len('hello') // 正常
len([1, 2, 3]) // 正常
len(Math.random() > 0.5 ? 'hello' : [1, 2, 3]) // 报错,因为这里返回的是联合类型,而len返回的是数字类型
示例4的优化:
function len(x: any[] | string) {
return x.length
}
len('hello') // 正常
len([1, 2, 3]) // 正常
len(Math.random() > 0.5 ? 'hello' : [1, 2, 3]) // 正常
提示:在可能的情况下,总是倾向于使用联合类型的参数而不是重载参数。
示例6:重载中的this
interface User {
admin: boolean
}
interface DB {
filterUsers(filter: (this: User) => boolean): User[]
}
const db: DB = {
filterUsers: (filter: (this: User) => boolean) => {
let user1: User = {
admin: true
}
let user2: User = {
admin: false
}
return [user1, user2]
}
}
const admins = db.filterUsers(function (this: User) {
return this.admin
})
console.log(admins) // [ { admin: true }, { admin: false } ]
// 箭头函数:报错 => An arrow function cannot have a 'this' parameter
const admins = db.filterUsers((this: User) => {
return this.admin
})
好了,分享结束,谢谢点赞,下期再见。
标签:function,return,函数,console,number,TS,参数,系列,string From: https://blog.csdn.net/m0_37943716/article/details/142645579