我有一个函数,其中param可以是字符串或未定义,但是如果未定义,则验证检查会引发错误。任何进一步的代码都可以保证定义了param,但是我现在正与可能未定义的TypeScript强制转换进行斗争。 TypeScript处理此问题的好方法是什么?
import { validatePetFields } from "../models/pets";
interface controllerParams {
req: {
petName?: string;
};
}
export default async ({ req }: controllerParams): Promise<any> => {
validatePetFields(req, [
"petName",
]); // this function intentionally throws a JS error if petName is undefined
console.log(req.petName.charAt(0).toUpperCase() + req.petName.slice(1)); // throws TypeScript error: Object is possibly 'undefined'
};
答案 0 :(得分:0)
您可以使用类型保护,但必须将validate调用包装在if语句中。这基本上告诉编译器,如果该函数返回true,则在if块内,req的类型现在是派生类型,该类型具有所需的所有那些键(作为参数传递)。
类似的东西:
type HasKeys<T, K extends keyof T> = T & { [Key in K]-?: T[Key] };
// function in a function to infer the key types
// unfortunately it can't infer the type of the req
// since it needs to be passed in the second function
// you could fix type inference for req by passing it as an argument to both functions
function validatePetFields<T>() {
return function <K extends keyof T>(obj: T, ...keys: K[]): obj is HasKeys<T, K> {
for (const key of keys) {
if (obj[key] === void 0) {
throw new Error('not valid');
}
}
return true;
};
}
interface Request {
petName?: string;
}
export default async (req: Request): Promise<any> => {
if (validatePetFields<Request>()(req, 'petName')) {
// no more error since petName is not optional here :)
console.log(req.petName.charAt(0).toUpperCase() + req.petName.slice(1));
}
};