I am trying to achieve structural typesafety with a curried function where the first argument is the key of an object and the return curry function it's argument takes the target (object).
I have prepared a fully working playground, as it much easier to explain there: typescript playground
// I have a map of Resources where the keys are equal to the resource it's type
type Resources = {
user: {
id: string
type: 'user'
attributes: {
name: string
age: number
last_name: string
}
},
// uncomment this section to break function underneath
// usergroup: {
// id: string
// type: 'usergroup'
// attributes: {
// mosterd: string
// group: string
// }
// }
}
type ResourceTypes = keyof Resources
// user|usergroup
type UserAttributes = keyof Resources['user']['attributes']
// name|age|last_name
function constrain<
T extends { type: ResourceTypes },
A extends keyof Resources[T['type']]['attributes']
> (attribute: A) {
return (resource: T) => {
}
}
// Is it possible to get typesafety for the attribute argument
// when resource argument has been given, like following example?
const result = constrain('name')({ type: 'user' })
type AllAttributes = keyof Resources[ResourceTypes]['attributes']
// becomes never, I assume this is what is happening in the constrain function but why cant it infer the ResourceType?