Typescript有条件地需要参数



我想写一个函数,接受一些参数,它们应该是可选的,但如果它们存在,那么我希望需要其他参数。

这里有一个非常愚蠢的例子:

type PersonInfo = {
name: string; 
age: number; 
pets?: boolean; 
petNames?: string[]; 
}
const recordPersonInfo = (options: PersonInfo) => {
database.save(options); 
}

所以pets属性可以省略,但如果它是true,那么我希望petNames是必需的。我如何告诉Typescript这样做?

您可以使用并集类型:pets属性是一个判别式,因此如果您在if块中写入if(options.pets),则options将缩小为肯定具有petNames属性。

type PersonInfo = {
name: string; 
age: number;
} & ({
pets?: false;
} | {
pets: true; 
petNames: string[]; 
})
const recordPersonInfo = (options: PersonInfo) => {
database.save(options); 
}

利用函数重载,您可以执行以下操作:

type PersonInfoWithPets = PersonInfo & { pets: true; petNames: string[] };
type PersonInfoWithoutPets = PersonInfo & { pets?: false; petNames?: undefined };

function recordPersonInfo(options: PersonInfoWithPets): void;
function recordPersonInfo(options: PersonInfoWithoutPets): void;
function recordPersonInfo(options: PersonInfo): void {
}
recordPersonInfo({
name: 'name',
age: 0,
});
recordPersonInfo({
name: 'name',
age: 0,
pets: false,
});
recordPersonInfo({
name: 'name',
age: 0,
pets: true,
petNames: [],
});
// This errors because `pets` but no `petNames`
recordPersonInfo({
name: 'name',
age: 0,
pets: true,
});
// This errors because `petNames` but no `pets`
recordPersonInfo({
name: 'name',
age: 0,
petNames: ['hi'],
});
// NOTE: This also errors because `pets` is a boolean here, not strictly true/false
recordPersonInfo(null! as PersonInfo);

老实说,TypeScript并不能提供一个完美的解决方案。在这种特定的情况下,你可以说";CCD_ 9的存在(和空(应该取代对CCD_;当然在这种情况下,我们躲过了两次过载,但更复杂的情况可能会导致需要更多的过载。

当然,您可以正确地记录函数,并在仍然给出错误输入时抛出错误。

最新更新