In the following example, is it possible for the type of P
to be inferred from the entries in the props
array, rather than having to define it twice?
type A = {
one: boolean
two: number
three: string[]
four: string
}
type Definition<T, P extends (keyof T)[]> = {
props: P
}
const def: Definition<A, ['one', 'three', 'four']> = {
props: ['one', 'three', 'four']
}
Note - the above example is massively simplified for the purpose of this question. The type of P
is also needed to calculate additional parts of a mapped type
I'm assuming you need to manually specify the type parameter A
. One thing that I do in those cases is have a kind of “factory function pair” like in the following. The idea is that the outer function lets you specify the type parameter you want, and the type parameter from the inner function is inferred:
type A = {
one: boolean
two: number
three: string[]
four: string
}
type Definition<T, P extends (keyof T)[]> = {
props: P
}
function makeDef<T>() {
return function<const P extends (keyof T)[]>(def: Definition<T, P>) {
return def
}
}
const def1 = makeDef<A>()({
props: ['one', 'three', 'four']
})
Here, def1
has type Definition<A, ["one", "three", "four"]>
. Sure, the syntax gets a bit loaded, but it works.
Also note that specifying const
before the definition of the type parameter P
on the inner function allows the inference to give as type exactly ["one", "three", "four"]
, whereas without the const, it would be ("one" | "three" | "four")[]
.