如何让 TypeScript 知道我的变量不再未定义
2021-12-20
2847
这是我的情况:
我正在使用
Remix 加载器
,它从 URL 获取参数,但参数定义为
string | undefined
如果变量为
undefined
,我想抛出一个
重定向
export const loader: LoaderFunction = async ({ params }) => {
const { myVar } = params; // myVar: string | undefined
definedOrRedirect(myVar, "/"); // Checks if undefined
return fetchSomething(myVar); // myVar: string | undefined
};
有没有办法让 typescript 知道如果它没有抛出
myVar
就不是未定义的?
2个回答
您可以将
throwIfUndefined
设为
断言函数
,以将其参数的类型缩小为域中不包含
undefined
的类型。断言函数具有形式为
asserts x is Y
的
断言类型谓词
作为其返回类型,其中
x
是该函数参数之一的名称,
Y
是
typeof X
的子类型,我们将
x
缩小为假设函数成功返回。断言函数不能返回已定义的值;它们基本上是
void
返回函数。
对于
throwIfUndefined
,以下是执行它的正常方法,作为函数语句:
function throwIfUndefined<T>(x: T | undefined): asserts x is T {
if (typeof x === "undefined") throw new Error("OH NOEZ");
}
您也可以将其写为箭头函数,但您需要明确 注释 变量及其类型,以便控制流分析正确进行:
const throwIfUndefined: <T, >(x: T | undefined) => asserts x is T = x => {
if (typeof x === "undefined") throw new Error("OH NOEZ");
}
两种方式都可以:
const Index = ({ params }: { params: { myVar: string | undefined } }) => {
const { myVar } = params // myVar: string | undefined
// myVar.toUpperCase // <-- error, Object is possibly 'undefined'
throwIfUndefined(myVar);
return myVar.toUpperCase() // no error now
}
try {
console.log(Index({
params: {
myVar: Math.random() < 0.5 ? "hello" : undefined
}
})) // 50% "HELLO"
} catch (e) {
console.log(e); // 50% "OH NOEZ"
}
jcalz
2021-12-20
您可以跳过
definedOrRedirect
并使用显式检查:
export const loader: LoaderFunction = async ({ params }) => {
const { myVar } = params; // myVar: string | undefined
if (myVar == undefined) {
return redirect("/");
}
return fetchSomething(myVar); // myVar: string
}
或者您可以保留
definedOrRedirect
并使用断言声明它,如
jcalz
所建议的:
function definedOrRedirect(variable, path): asserts variable is string
{
if (variable == undefined) {
return redirect(path);
}
}
export const loader: LoaderFunction = async ({ params }) => {
const { myVar } = params; // myVar: string | undefined
definedOrRedirect(myVar, "/");
return fetchSomething(myVar); // myVar: string
}
md2perpe
2021-12-20