Search code examples
typescripttypesextends

Extending a Type to Create Child Type


I am working with TypeScript and am wondering how to achieve a child type of another. I don't know exactly how to describe what I am after, so let me just show an example.

type Person = {
 name: string;
 type: PersonType
}

type Child = Person & {
 type: PersonType.child,
}

enum PersonType {
 adult = "adult",
 child = "child",
}

const people: Person[] = [...];
const children: Child[] = people.filter(p => p.type === PersonType.child);

Is this something I would use a generic for? I would think this is straight forward and I'm just missing a piece. Thanks!


Solution

  • You added redundant = sign to enum.

    type Person = {
        name: string;
        type: PersonType
    }
    
    type Child = Person & {
        type: PersonType.child,
    }
    
    enum PersonType {
        adult = "adult",
        child = "child",
    }
    
    type TestChild = Person extends Child ? true : false // false
    type TestPerson = Child extends Person ? true : false // true
    
    
    const people: Person[] = [{ name: 'John', type: PersonType.adult }, { name: 'Tim', type: PersonType.child }];
    const children: Child[] = people.filter(p => p.type === PersonType.child);
    

    The problem is that Child extends Person, but not vice versa. You can't just use explicitly type Child[] for children constant, because Person does not extends Child

    Here is interesting article about covariance.

    But, you can achieve desired behaviour, just use filter as a typeguard:

    const children: Child[] = people.filter((p):p is Child => p.type === PersonType.child); // ok
    

    More interesting examples, You can find here