我有两个函数article.getByCustomerAndCategory
(需要两个参数)和article.getById
(需要一个参数)。
function getArticle ({ customer_id, category_id, article_id }: Partial<Article>): Article {
if (customer_id && category_id) {
return article.getByCustomerAndCategory({
customer_id,
category_id,
});
}
if (article_id) {
return article.getById({
article_id
});
}
throw new Error('invalid argument');
};
也尝试过:
type articleInput = { customer_id, category_id } | { article_id };
function getArticle (input: articleInput): Article {
if (input.customer_id && input.category_id) {
return serviceRecurrence.get({
customer_id,
category_id,
});
}
if (input.article_id) {
return serviceRecurrence.getById({
article_id
});
}
throw new Error('invalid argument');
};
我希望将两者结合成一个函数,可以采用customer_id
和category_id
或仅采用article_id
。返回类型都相同。
答案 0 :(得分:1)
您的方法距离不太远。使用联合表示可以传递给函数的两种参数是一个好主意。您缺少的部分是类型防护,可以将input
参数的类型缩小为其中一个并集成员:
// Assumed declarations Types
interface Article {
customer_id: number, category_id: number
}
let serviceRecurrence: {
get(p: {
customer_id: number, category_id: number
}): Article
getById(p: {
article_id: number
}): Article
}
type articleInput = { customer_id: number, category_id: number } | { article_id: number };
// The function
function getArticle (input: articleInput): Article {
if ('article_id' in input) { // in typeguard
return serviceRecurrence.getById({
... input // input is { article_id: number } and we can use a spread operator to create the input for getById
});
}
else {
return serviceRecurrence.get({
... input // input is { customer_id: number, category_id: number } and we can use a spread operator to create the input for get
});
}
throw new Error('invalid argument');
};