#typescript
Вопрос:
У меня есть функция, которая немного похожа на эту:
function getOutput<TInputType>(input: TInputType): TInputType {
if (typeof input === 'string') {
return 'abc';
} else {
return input;
}
}
В этом коде есть ошибка TS в третьей строке: Type 'string' is not assignable to type 'TInputType'.
Но так как мы проверяем , что typeof input
это string
так, то, возвращаясь 'abc'
, мы возвращаем тот же тип, input
что и . Но, похоже, TS не в состоянии сделать такой вывод в данном случае.
Есть ли способ сделать ТС счастливой здесь? (кроме кастинга, @ts-игнорировать и друзей)
Ответ №1:
Машинопись верна, чтобы сообщить об ошибке. Рассмотрим вызов функции getOutput<'xyz'>('xyz')
. Согласно определению функции, тип возвращаемого значения должен быть 'xyz'
таким, поскольку именно таким является параметр типа TInputType
для этого вызова. Однако написанный код фактически возвращается 'abc'
, который не может быть присвоен типу 'xyz'
.
Таким образом , нет никакого способа «сделать машинопись счастливой» с помощью этого кода, за исключением использования преднамеренно некорректного поведения, такого как утверждение типа или @ts-ignore
, потому что сам код является некорректным.
Ответ №2:
Вы можете добавить перегрузку функций, чтобы лучше различать две ситуации:
function getOutput(input: string): string;
function getOutput<P>(input: P): P;
function getOutput<P, T extends string | P>(input: T): T | string {
if (typeof input === 'string') {
return 'abc';
} else {
return input;
}
}
const iAmString = getOutput('a'); // string
const iAmAnything = getOutput(2 3); // number
const iAmAnythingElse = getOutput(new Date()); // Date
Комментарии:
1. Это ошибка с TS 4.4.2 в playground: typescriptlang.org/play?ts=4.4.2#code/…
2. Можете ли вы более конкретно рассказать о самом типе? Это помогло бы. Если тип
TInputType = string | number
, например, работает.3. Это может быть что угодно, никаких ограничений.
4.
type TInputType = any;
все еще работает. Для этого требуется определение типа.5. Я бы хотел, чтобы TInputType был параметром общего типа , а не просто
any
any
изменял, хотя я пойду туда, если нет других вариантов.