Вот чего я хочу добиться:
function isString<T>( value: T ): value is T extends string ? T : string {
return typeof value === "string";
}
function isNotString<T>( value: T ): T extends string ? unknown : T {
return typeof value !== "string";
}
Но я получаю сообщение об ошибке: «Тип предиката типа должен быть назначен типу его параметра». что и ожидается.
Кстати, я не хочу добиться следующего:
function isString<T>( value: T ): Extract<T, string> {
return typeof value === "string";
}
function isNotString<T>( value: T ): Exclude<T, string> {
return typeof value !== "string";
}
Потому что оба из них могут вывести never
тип, который мне не нужен. Тем не менее, мне всегда нужно иметь дело с известным типом.
Не могли бы вы помочь мне добиться этого с помощью TypeScript? :-)
Ответить на ответы
Спасибо вам большое за содержательные ответы, ребята. Вот мои ответы:
Не беспокойтесь о создании защиты типа isNotString, потому что она не будет делать то, что вы хотите. Вместо этого проверьте, что isString имеет значение false, и машинописный текст все правильно выведет.
Вы видите что-то не так со следующей функцией? Если я не ошибаюсь, я думаю, что он достигает того, чего я ожидал.
function isNotString<T>( value: T ): value is Exclude<T, string> {
return typeof value === "string";
}
Мне лично нравится включать общий тип и утверждать, что значение - это T & string, а не просто value is string, чтобы никакая информация не терялась, если тип уже известен как конкретное подмножество строки.
Мне нравится этот подход, но раньше я добивался этого странным образом. Я не собираюсь рассказывать об этом здесь, так как это был безумный подход.
У нас не было никогда в нашем операторе возврата, но мы по-прежнему получаем никогда в нашем коде, потому что это единственный логический тип, если наша переменная a: string не является строкой.
Не могу с этим согласиться. Вчера я точно был не в своем уме. :-)
Стоит отметить, что встроенные средства защиты типов в машинописном тексте на самом деле не уточняют тип в отрицательном случае. Это просто показывает, что вы не можете делать это должным образом, имея дело с неизвестным типом, таким как T.
Я согласен, дорогой. Я просто хочу иметь это для подробностей. Может я ошибаюсь, но isNotString
мне кажется более многословным, чем ! isString
.
Вы можете, пожалуйста, взгляните на это Детская площадка?
Я вижу, что Exclude
работает, как ожидалось, но value: T | string
- нет. Не стесняйтесь указать, если я что-то пропустил.