#Type that changes type of values based on key?

17 messages · Page 1 of 1 (latest)

dark goblet
#

I'd like a type to express the following transformation:

// any key in this union that maps to a string value
// in the original type should become a date in the transformed // type
type DateFields = "createdAt" | "startDate"

type originalType = {
    createdAt: string
    foo: string
    bar: {createdAt: string,
            startDate: string,
        foo: number,
        baz: string[]
    }
}

type newType = {
    createdAt: Date
    foo: string
    bar: {createdAt: Date
            startDate: Date
        foo: number
        baz: string[]}
    }

Basically I want a type to express the effect of the (recursive) function that traverses an object, checks if it has certain keys, and changes the value associated with that key from a string to a Date instance.

I'm having trouble expressing a conditional mapped type where there's a conditional branching off the type of the keys. Any help would be appreciated!

fading delta
#

type ToDate<T, K> = { [P in keyof T]: P extends K ? Date : ToDate<T[P], K> }

#

what if the type is { createdAt: { createdAt: string } }

#

then what

dark goblet
#

hmm ideally I'd define a type where createdAt only ever keys for strings

#

that situation will not occur

#

thanks for the answer! This is much simpler than what I was trying to do.

pale blade
#
type Transform<T> = {
    [K in keyof T]: K extends DateFields
        ? Date
        : Transform<T[K]>
}
fading delta
#

basically the same thing

dark goblet
#

suppose I wanted to add the condition that the value being changed must be a string

#

is it possible to express this?

fading delta
#

replace the condition with [P, string] extends [K, T[P]]

dark goblet
#

thanks!

#

i didn't know i could use that syntax

fading delta
#

i think this affects distribution if T[P] is a union ..

fading delta
dark goblet
#

aha, so [P in keyof T] is just constructing a tuple of keys