Search code examples
typescriptunion-types

Union types : Property does not exist on type object


Object type is not recognized on an interface property with multiple types. In my case, answer property with PostalAnswer type.

interface Question {
    id: number;
    answer: string | string[] | PostalAnswer;
}
interface PostalAnswer { address: string; city: string; code: string; }

const formQuestions: Question[] = [
    {
        id: 0,
        answer: 'Bonjour'
    },
    {
        id: 1,
        answer: { address: '1 rue', city: 'Paris', code: '75001' }
    }
];

console.log(formQuestions[1].answer.address);

typescript playground

I get this error on the last line:

Property 'address' does not exist on type 'string | PostalAnswer | string[]'. Property 'address' does not exist on type 'string'. ts(2339)

Note: If answer property has only one type PostalAnswer, there is no error anymore.


Solution

  • You should use a type guard.

    interface Question {
        id: number;
        answer: string | string[] | PostalAnswer;
    }
    interface PostalAnswer { address: string; city: string; code: string; }
    
    const formQuestions: Question[] = [
        {
            id: 0,
            answer: 'Bonjour'
        },
        {
            id: 1,
            answer: { address: '1 rue', city: 'Paris', code: '75001' }
        }
    ];
    
    const question = formQuestions[1];
    if (typeof question.answer === "object" && !Array.isArray(question.answer)) { // Typeguard
        console.log(question.answer.address);
    }
    

    You can also make a function:

    console.log(isPostalAnswer(formQuestions[1].answer) && formQuestions[1].answer.address);
    
    function isPostalAnswer(potentialAnswer: any): potentialAnswer is PostalAnswer {
        return typeof potentialAnswer === "object"
            && "address" in potentialAnswer
            && "city" in potentialAnswer
            && "code" in potentialAnswer;
    }