Home > Blockchain >  Instanceof type guard can't narrow the type of a variable used inside a callback
Instanceof type guard can't narrow the type of a variable used inside a callback

Time:09-09

const userAPI = {
  async getById() { }
}

const batchedUpdates = (callback: () => any) => {
  callback();
}
const setError = (error: Error | null) => { }

async function main() {
  const result: { error: Error | null, data: any | null } = {
    error: null,
    data: null
  }
  try {
    const user = await userAPI.getById();
  } catch (error) {
    if (error instanceof Error) {
      result.error = error;
      batchedUpdates(() => {
        setError(error);
      })
    }
  }
}

Got error at the line of setError(error) statement:

Argument of type 'unknown' is not assignable to parameter of type 'Error | null'.(2345)

I don't want to repeat the instanceof type guard in the callback of batchedUpdates, what's the right approach to handle this situation? Thanks.

TypeScript Playground

CodePudding user response:

Control Flow Analysis does not cross callback boundaries. This is explained in the canonical issue Trade-offs in Control Flow Analysis

A workaround is to use a local variable to freeze the type:

const userAPI = {
  async getById() { }
}

const batchedUpdates = (callback: () => any) => {
  callback();
}
const setError = (error: Error | null) => { }

async function main() {
  const result: { error: Error | null, data: any | null } = {
    error: null,
    data: null
  }
  try {
    const user = await userAPI.getById();
  } catch (error) {
    if (error instanceof Error) {
      result.error = error;
      const localError = error
      batchedUpdates(() => {
        setError(localError);
      })
    }
  }
}

Playground Link

  • Related