Вызов функции хотя бы с одним аргументом, какой тип?
Есть функция
type Time = {
days?: number
hours?: number
minutes?: number
seconds?: number
}
const timeToMilliseconds = ({ days, hours, minutes, seconds }: Time) => {
if (days) return days * 24 * 60 * 60 * 1000;
if (hours) return hours * 60 * 60 * 1000;
if (minutes) return minutes * 60 * 1000;
if (seconds) return seconds * 1000;
};
Проблема в том, что мне постоянно приходится делать проверку на undefined когда я ее использую, это связано с тем что функция может вернуть undefined вместо числа, это произойдет в том случае если она будет вызвана без аргументов.
Вопрос в том как создать тип который будет указывать на то что в функция должна быть вызвана хотя бы с одним аргументом, для того что бы исключить возврат undefined ?
Ответы (1 шт):
Автор решения: qwabra
→ Ссылка
namespace A
для того что бы исключить возврат undefined
namespace A {
const [days, hours, minutes, seconds] = [1, 2, 3, 4]
type Time = {
days?: number
hours?: number
minutes?: number
seconds?: number
}
namespace T1 {
const timeToMilliseconds = ({ days, hours, minutes, seconds }: Time) => {
if (days) return days * 24 * 60 * 60 * 1000;
if (hours) return hours * 60 * 60 * 1000;
if (minutes) return minutes * 60 * 1000;
if (seconds) return seconds * 1000;
return 0
}
//@ts-expect-error
timeToMilliseconds({})// плохо - нет ошибки
timeToMilliseconds({ days })// ok
timeToMilliseconds({ hours })// ok
timeToMilliseconds({ minutes })// ok
timeToMilliseconds({ seconds })// ok
//@ts-expect-error
timeToMilliseconds({ days, hours, minutes, seconds })// нет ошибки
}
namespace T2 {
const timeToMilliseconds = ({ days, hours, minutes, seconds }: Time) => {
if (days) return days * 24 * 60 * 60 * 1000;
if (hours) return hours * 60 * 60 * 1000;
if (minutes) return minutes * 60 * 1000;
if (seconds) return seconds * 1000;
else throw new TypeError('days, hours, minutes and seconds is not set')
}
//@ts-expect-error
timeToMilliseconds({})// плохо - нет ошибки
timeToMilliseconds({ days })// ok
timeToMilliseconds({ hours })// ok
timeToMilliseconds({ minutes })// ok
timeToMilliseconds({ seconds })// ok
//@ts-expect-error
timeToMilliseconds({ days, hours, minutes, seconds })// нет ошибки
}
}
namespace B
функция должна быть вызвана хотя бы с одним аргументом
namespace B {
const [days, hours, minutes, seconds] = [1, 2, 3, 4]
namespace T1 {
type Time_2 = { days: number } | { hours: number } | { minutes: number } | { seconds: number }
const timeToMilliseconds = (time: Time_2) => {
if ('days' in time) return time.days * 24 * 60 * 60 * 1000;
if ('hours' in time) return time.hours * 60 * 60 * 1000;
if ('minutes' in time) return time.minutes * 60 * 1000;
if ('seconds' in time) return time.seconds * 1000;
else throw new TypeError('days, hours, minutes and seconds is not set')
}
//@ts-expect-error
timeToMilliseconds({})// ok - TS сообщает об ошибке
timeToMilliseconds({ days })// ok
timeToMilliseconds({ hours })// ok
timeToMilliseconds({ minutes })// ok
timeToMilliseconds({ seconds })// ok
//@ts-expect-error
timeToMilliseconds({ days, hours, minutes, seconds })// нет ошибки
}
namespace T2 {
// interface $timeToMilliseconds {
type $timeToMilliseconds = {
(time: { days: number }): number;
(time: { hours: number }): number;
(time: { minutes: number }): number;
(time: { seconds: number }): number;
}
const timeToMilliseconds: $timeToMilliseconds = (time: Record<any, any>) => {
if ('days' in time) return time.days * 24 * 60 * 60 * 1000;
if ('hours' in time) return time.hours * 60 * 60 * 1000;
if ('minutes' in time) return time.minutes * 60 * 1000;
if ('seconds' in time) return time.seconds * 1000;
else throw new TypeError('days, hours, minutes and seconds is not set')
}
//@ts-expect-error
timeToMilliseconds({})// ok - TS сообщает об ошибке
timeToMilliseconds({ days })// ok
timeToMilliseconds({ hours })// ok
timeToMilliseconds({ minutes })// ok
timeToMilliseconds({ seconds })// ok
//@ts-expect-error
timeToMilliseconds({ days, hours, minutes, seconds })// TS сообщает об ошибке
}
}