Проблема в том, что код здесь:
onClick={() => {
// I get a warning from this!
needsString(var1);
}}
не будет выполнен одновременно с этим кодом:
if (! var1)
throw new Error("bad, bad varN");
// This call is warning-free
needsString(var1);
Более того, var1
является изменяемой ссылкой так что с точки зрения TypeScript может измениться между проверкой, если она пуста, на самом деле вы ее используете. Например, рассмотрим этот пример кода:
//it's populated
var myVar = "hello";
//verify it's populated
if(!myVar) throw Error("WRONG!");
//absolutely positively `myVar` is populated
//set this to execute later
setTimeout(() => console.log("myVar", myVar));
//change it
myVar = undefined;
Таким образом, TypeScript может только определить, что var1
может быть переназначен. Функция useParams()
возвращает объект, типизированный как
{ [K in keyof Params]?: string | undefined; }
, что означает, что возможный тип для var1
равен string | undefined
. Если значение изменяется (TypeScript не может определить, делает это или нет), то он может видеть, что undefined
недопустимо.
Использовать const
Вы можете просто объявить его как const { var1 }
( Playground Link ), что делает его тип string
только потому, что он гарантирует компилятору, что вы не измените его между объявлением и использованием.
Утверждение типа
В качестве альтернативы можно явно указать тип string
: var { var1 } = useParams() as { var1: string };
Playground Link . Компилятор согласился бы с тем, что возможно вы переназначили его, но он по крайней мере знал бы, что единственная возможная вещь, на которую вы бы изменили переменную, - это другая строка. Который удовлетворяет типу, используемому позже, и таким образом будет работать. Однако это требует утверждения типа и, как всегда, полагается на то, что вы уверены , что это так, иначе вы можете получить ошибку времени выполнения, которую не увидит компилятор TypeScript (потому что вы «ослепили») это, намеренно)
const
только после проверки
Если вам неудобно устанавливать постоянную var1
по какой-либо причине - либо вы ее измените, либо что-то еще, тогда вы можете просто выполните обычную проверку для var1
и затем установите новую константу:
if (! var1)
throw new Error("bad, bad varN");
const checkedVar1 = var1;
/* ... */
onClick={() => {
// I get a warning from this!
needsString(checkedVar1);
}}
Playground Link
Это все еще работает и будет удовлетворять компилятору TypeScript, который checkedVar1
(Полагаю, вы бы назвали это чем-то более разумным) не меняется между определенным назначением чего-либо, что определенно является строкой, и фактическим использованием.