看下面这个函数
interface Student {
id: number;
name: string;
class: string;
sex: string;
}
function matriculation(student: Student) {
//...
}
我们要调用它,就需要传递一个实现了Student约束的对象进去
interface Student {
id: number;
name: string;
class: string;
sex: string;
}
function matriculation(student: Student) {
//...
}
let lihua: Student = {
id: 1,
name: 'Lihua',
class: '1A',
sex: 'Female',
};
matriculation(lihua);
到这,都没什么问题,
现在我希望这个函数打印一遍传进来的参数的各个属性
如下在不使用解构传参的情况下,
function matriculation(student: Student) {
console.log(`姓名${student.name}`);
console.log(`班级${student.class}`);
console.log(`性别${student.sex}`);
console.log(`学号${student.id}`);
}
我们会发现,写法非常臃肿,我们每一次都要使用studen.,
这时候我们可以简化一下,使用解构传参
function matriculation({ id, name, sex, grade }: Student) {
console.log(`学号${id}`)
console.log(`姓名${name}`)
console.log(`性别${sex}`)
console.log(`年级${grade}`)
}
这样就简洁多了,
更进一步的使用,
比如现在需求改了高年级的同学因为学校已经有他的信息了,所以入学只需要学号就能办理入学了,其他的值可以先使用默认值,
所以我们得把函数和接口改成如下这种
interface Student {
id: number;
name: string;
grade: string;
sex: string;
}
type OptionalStudent<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
这样,函数就能接受某些值为空的参数
然后就是赋值默认值了,
如果不适用解构传参
type OptionalStudent<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
function matriculation(student: OptionalStudent<Student, 'name' | 'grade' | 'sex'>) {
const defaultStudent: Student = {
id: 0,
name: 'Unknown',
grade: 'Unknown',
sex: 'Unknown',
};
const studentWithDefault = { ...defaultStudent, ...student };
console.log(`学号${studentWithDefault.id}`)
console.log(`姓名${studentWithDefault.name}`)
console.log(`年级${studentWithDefault.grade}`)
console.log(`性别${studentWithDefault.sex}`)
}
这代码又臃肿了,还得先声明一个对象,然后再将对象解构再解构传过来的参数,再覆盖
不光写起来臃肿,逻辑也臃肿
这种情况我们也可以使用解构传参来改变,因为解构是支持默认值的,如下
type OptionalStudent<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
function matriculation({ id, name = 'Unknow', grade = 'Unknow', sex = 'Unknow' }: OptionalStudent<Student, 'name' | 'grade' | 'sex'>) {
console.log(`学号${id}`)
console.log(`姓名${name}`)
console.log(`年级${grade}`)
console.log(`性别${sex}`)
}