asnaeb
asnaeb

Reputation: 745

Typescript conditional extends with nested object

I am building a type that checks if a member of a class-type is an object and if so, a specific type must be assigned. I provide a more explanatory example below.

Here we have the class example we are going to use.

declare class myObject {
    name?: string
    id?: number
    parent?: {
        child: number
    }
}

Here we have the type i am trying to make

type myType<T> = {
    [K in keyof T]: T[K] extends {[k:string]:any} ? T[K] : "something"
}

It should check that parent member is in fact an object of that type and allow something like this

const example: myType<myObject> = {
    parent: {
        child: 0
    },
    name: "something"
    id: "something"

But it doesn't because parent? doesn't get checked successfully against {[k:string]:any}. This happens because parent? is an optional member. If i change parent? to parent it works as expected. To try and work around this I tried switching {[k:string]:any} with {[Z in keyof T[K]]?: T[K][Z]} but i observed the same exact behaviour.

A link to TS Playground

Upvotes: 2

Views: 920

Answers (2)

Renato
Renato

Reputation: 349

You are right when you say this happens because parent? is an optional member.

But what does it mean to be an optional member?

In JS it means the property can either have a value or be undefined.

In TS, it means that the type of parent? is actually something like: {[k:string]: any} | undefined

The code below solves the error on the linked TS playground.

type myType<T> = {
    [K in keyof T]?: T[K] extends ({[k:string]: any} | undefined) ? T[K] : "something"
}

Upvotes: 1

lukasl-dev
lukasl-dev

Reputation: 1118

If I understand your problem correctly, then you can do the following:

type MyType<T> = {
    [K in keyof T]: T[K] extends {[k:string]:any} | undefined ? T[K] : "something"
}

The ? gives the property the possibility to be undefined (optional), therefore you can replace {[k:string]:any} with [k:string]:any} | undefined.

Upvotes: 1

Related Questions