1. 基本知识
TypeScript 中,问号 ? 常用于表示函数参数、对象属性等是可选的
可选参数在实际开发中非常有用,可以提高代码的灵活性和可读性
指的是在调用函数或创建对象时,可以选择性地提供这些参数或属性。如果未提供,可选参数将被视为 undefined
基本的语法如下:在函数参数名后添加问号 ?,即可将其声明为可选参数
function functionName(param1: type, param2?: type) {
// 函数体
}
注意:
- 可选参数必须放在必需参数的后面
- 未提供可选参数时,其值为 undefined
2. Demo
为更好的对比,先讲述没有?的
2.1 差异
此处主要讲解可选参数 和 默认参数的差异
可选参数:未提供时为 undefined,需要手动在函数体内处理未定义的情况
默认参数:未提供时使用预设的默认值,在参数声明时直接指定默认值
function greetOptional(name: string, greeting?: string): string {
return `${greeting || "Hello"}, ${name}!`;
}
function greetDefault(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
console.log(greetOptional("Alice")); // 输出: Hello, Alice!
console.log(greetDefault("Bob")); // 输出: Hello, Bob!
2.2 可选参数
示例 1:简单的可选参数
greeting 参数是可选的;当未提供 greeting 时,默认使用 “Hello” 作为问候语
function greet(name: string, greeting?: string): string {
if (greeting) {
return `${greeting}, ${name}!`;
} else {
return `Hello, ${name}!`;
}
}
console.log(greet("Alice")); // 输出: Hello, Alice!
console.log(greet("Bob", "Good morning")); // 输出: Good morning, Bob!
示例 2:多个可选参数
这里的 lastName 和 middleName 都是可选参数,可以根据需要提供
function buildName(firstName: string, lastName?: string, middleName?: string): string {
let fullName = firstName;
if (middleName) {
fullName += ` ${middleName}`;
}
if (lastName) {
fullName += ` ${lastName}`;
}
return fullName;
}
console.log(buildName("John")); // 输出: John
console.log(buildName("John", "Doe")); // 输出: John Doe
console.log(buildName("John", "Doe", "William")); // 输出: John William Doe
3. 接口和类型
接口中的可选属性
接口 Person 定义了三个属性,其中 age 和 address 是可选的
创建对象时,可以选择性地提供这些可选属性
interface Person {
name: string;
age?: number;
address?: string;
}
interface Person {
name: string;
age?: number;
address?: string;
}
const person1: Person = {
name: "Alice"
};
const person2: Person = {
name: "Bob",
age: 25
};
const person3: Person = {
name: "Charlie",
age: 30,
address: "123 Main St"
};
console.log(person1); // 输出: { name: "Alice" }
console.log(person2); // 输出: { name: "Bob", age: 25 }
console.log(person3); // 输出: { name: "Charlie", age: 30, address: "123 Main St" }
类型别名中的可选属性
类型别名 Product 中,price 和 description 是可选属性
type Product = {
name: string;
price?: number;
description?: string;
};
type Product = {
name: string;
price?: number;
description?: string;
};
const product1: Product = {
name: "Laptop"
};
const product2: Product = {
name: "Phone",
price: 699
};
const product3: Product = {
name: "Tablet",
price: 499,
description: "A high-end tablet."
};
console.log(product1); // 输出: { name: "Laptop" }
console.log(product2); // 输出: { name: "Phone", price: 699 }
console.log(product3); // 输出: { name: "Tablet", price: 499, description: "A high-end tablet." }
4. 类和方法
1. 类的可选属性
类 Vehicle 中,year 属性是可选的。
在构造函数和方法中,需要检查 year 是否存在
class Vehicle {
make: string;
model: string;
year?: number;
constructor(make: string, model: string, year?: number) {
this.make = make;
this.model = model;
if (year) {
this.year = year;
}
}
getInfo(): string {
if (this.year) {
return `${this.make} ${this.model}, ${this.year}`;
}
return `${this.make} ${this.model}`;
}
}
const vehicle1 = new Vehicle("Toyota", "Corolla");
const vehicle2 = new Vehicle("Honda", "Civic", 2020);
console.log(vehicle1.getInfo()); // 输出: Toyota Corolla
console.log(vehicle2.getInfo()); // 输出: Honda Civic, 2020
2. 类方法的可选参数
add 方法的第三个参数 c 是可选的
根据是否提供 c,方法返回不同的计算结果
class Calculator {
add(a: number, b: number, c?: number): number {
if (c !== undefined) {
return a + b + c;
}
return a + b;
}
}
const calc = new Calculator();
console.log(calc.add(1, 2)); // 输出: 3
console.log(calc.add(1, 2, 3)); // 输出: 6