javascript - Typescript-inferensfeil - variabel med typen string endres til undefined inne i for-løkke
Jeg bruker await-to-js-biblioteket for feilhåndtering (metoden to i eksemplet nedenfor kommer fra biblioteket)
Av en eller annen grunn endres typen til en variabel til string | undefined inne i en for..of-løkke, når verdien av den samme variabelen er string utenfor løkken.
Vurder følgende eksempel (se testMethod for feil):
function to<T, U = Error>(
promise: Promise<T>,
errorExt?: object
): Promise<[U, undefined] | [null, T]> {
return promise
.then<[null, T]>((data: T) => [null, data])
.catch<[U, undefined]>((err: U) => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt);
return [parsedError, undefined];
}
return [err, undefined];
});
}
async function retrieveAccessToken(): Promise<string> {
const randomNumber = Math.random();
if(randomNumber < 0.5) {
throw new Error("Failed");
}
return "testToken";
}
function printAccessToken(accessToken: string) {
console.log(accessToken);
};
async function testMethod(): Promise<boolean> {
const accessTokenPromise = retrieveAccessToken();
const [err, accessToken] = await to(accessTokenPromise);
if(err){
console.log("Failed");
return false;
}
// No error here
printAccessToken(accessToken);
for(let i = 0 ; i < 5; i++){
// Error! Type Argument of type 'string | undefined' is not assignable to
// parameter of type 'string'.
printAccessToken(accessToken);
}
return true;
}
Dette ser ut til å bli løst ved å legge til en if-sjekk på accessToken, f.eks. if(!accessToken), men det gir ikke mening hvorfor typen til accessToken er string | undefined inne i for-løkken, men string utenfor den?
Typescript-lekeplass
Svar #1
TypeScript har problemer med å analysere typer i destruktureringssyntaks. For å få forventet oppførsel, tilordne den løste verdien av to til en lokal variabel, og referer til accessToken etter å ha sjekket err.
Endre :
const [err, accessToken] = await to(accessTokenPromise);
if(err){
console.log("Failed");
return false;
}
Inn i :
const toResult = await to(accessTokenPromise);
const [err] = toResult;
if(err){
console.log("Failed");
return false;
}
const [, accessToken] = toResult;
Lekplasslink
