Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

In TypeScript, why is the function return type not assigned to generic type as expected?

I have this code in TypeScript and the ParsedData generic type is not populated correctly. I don’t understand what’s preventing TS from inferring the correct type below.

function fromData<RawData, ParsedData>(rawData: RawData) {
    return function withParser(
        parser: (data: RawData) => ParsedData,
        renderer: (parsedData: ParsedData) => unknown
    ) {
        const parsedData = parser(rawData)
        
        return {
            renderedData: renderer(parsedData),
            parsedData
        }
    }
}

const hasData = fromData({ user: 1 })

hasData(
    (rawData) => rawData.user + 1,
    (parsedData) => parsedData + 100 // PROBLEM: 'parsedData' is of type 'unknown'.(18046) 
)

In general, I would like to call a function with some data and receive another function that can be called at a later time with a parser and renderer arguments that infer correct types throughout.

I’m expecting to see parsedData to be correctly typed in my IDE, so that I can more easily implement a renderer function using the return type of the parser function.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

This happens because ParsedData is a type parameter of fromData, and at the fromData call the ParsedData type has not been determined yet. You can fix it by instead parameterizing the returned function with ParsedData:

function fromData<RawData>(rawData: RawData) {
    return function withParser<ParsedData>(
        parser: (data: RawData) => ParsedData,
        renderer: (parsedData: ParsedData) => unknown
    ) {
        const parsedData = parser(rawData)

        return {
            renderedData: renderer(parsedData),
            parsedData
        }
    }
}
const hasData = fromData({ user: 1 })

hasData(
    (rawData) => rawData.user + 1,
    (parsedData) => parsedData + 100
    // (parameter) parsedData: number
)

TypeScript playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading