1

I am trying to created a custom type that replaces all types of a Generic parameter T to string[] but keeps all the property names even nested.

Expected behaviour: No error

interface Bar {
    lat: string,
    lng: string
}
interface Foo {
    id: string,
    bar: Bar
}
export type PartialDeepKeyOf<T> = { [id in keyof T]: string[] }

const baz: PartialDeepKeyOf<Foo> = {
    id: ['a','b'],
    bar: {
        lat: ['a','b'],
        lng: ['a','b'],
    }
}

Actual behaviour:

Type '{ lat: string[]; lng: string[]; }' is not assignable to type 'string[]'

1
  • 1
    Yes but "I am trying to create a custom type that replaces all types of a Generic parameter T to string[] but keeps all the property names even nested." Commented Jul 27, 2020 at 8:41

1 Answer 1

2

You need recursive type traversal

type PartialDeepKeyOf<T> = {
    [P in keyof T]: T[P] extends string
    ? string[]
    : PartialDeepKeyOf<T[P]>
};

Playground

Sign up to request clarification or add additional context in comments.

4 Comments

This works well, but relies on all the leaf properties being of a type string to be converted to the new type. I could extend that to string | number and other primitive types, but then becomes brittle if I have to list out any enums I use as well. Is there any way to change the condition to be something like extends Object and then otherwise have the type converted to the new type? I can't figure out how to do that in TypeScript.
If I use extends Record<string, any>, this loses the enforcement of the correct key structure.
@MattTreichel If I understand you correctly, then this should work.
Thanks, that probably does, it turns out my editor's error reporting made me think it wasn't working as intended. I spun this question off into a new thread here because I was impatient: stackoverflow.com/q/72692468/1917171

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.