I have a case like this:
function createCar(name: string, callback: () => void)
function buildEngine(name: string): Engine
function createCarWithEngine(carName: string, engineName: string, callback: (param: Engine) => void) {
let createdEngine = createdEngines.find((engine) => engine.name === engineName)
if (!createdEngine) createdEngine = buildEngine(engineName)
createCar(carName, () => callback(createdEngine)) // error here
}
VSCode tells me createdEngine
maybe undefined. However this is fine:
const fn = callback(createdEngine)
createCar(carname, () => fn)
Is this an intended behaviour?
CodePudding user response:
The 2 cases aren't equivalent.
In the second case you call callback
inside the function, in the first you defer the call for a later time.
This will fail with the same error
const fn = () => callback(createdEngine)
createCar(carname, fn)
This is related to the fact that TS cannot know what happens with createdEngine
because the function will be called later on. When you call createEngine
inside your function then it knows that the calls are done in sync so it narrows the type down.
Interesting enough if you ensure that the type of createdEngine
is Engine
at all times then this will work.
function createCarWithEngine(carName: string, engineName: string, callback: (param: Engine) => void) {
let createdEngine = createdEngines.find((engine) => engine.name === engineName) || buildEngine(engineName)
createCar(carName, () => callback(createdEngine)) // error here
}