Created
October 10, 2020 03:12
-
-
Save ai/3c58a27929298fef498c26d0decc4e83 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Post { | |
title: string = '' | |
text: string = '' | |
} | |
class Group { | |
title: string = '' | |
roles: string = '' | |
} | |
class User { | |
login: string = '' | |
age: string = '' | |
group: Group = new Group() | |
posts: Post[] = [] | |
} | |
type Class = new (...args: any) => any | |
type Fields<I extends InstanceType<Class>> = { | |
[key in keyof I]?: I[key] extends object[] | |
? boolean | Fields<I[key][0]> | |
: I[key] extends object | |
? boolean | Fields<I[key]> | |
: boolean | |
} | |
type DeepPick<I, F extends Fields<I>> = { | |
[key in keyof I]: I[key] extends object[] | |
? DeepPick<I[key][0], F[key]>[] | |
: I[key] extends object | |
? DeepPick<I[key], F[key]> | |
: F[key] extends true | |
? I[key] | |
: never | |
} | |
function useMap<K extends Class, F extends Fields<InstanceType<K>>> ( | |
cls: K, | |
fields: F | |
): [false, DeepPick<InstanceType<K>, F>] | [true | null] { | |
return {} as any | |
} | |
const fields: Fields<User> = { | |
login: true | |
} | |
const [isLoading, user] = useMap(User, { | |
login: true, | |
group: { | |
title: true | |
}, | |
posts: { | |
title: true | |
} | |
}) | |
if (user) { | |
// Positive | |
user.login = 'a' | |
user.group.title = '' | |
user.posts.forEach(post => { | |
post.title = 'Test' | |
}) | |
// Negative | |
user.age = 21 | |
user.group.roles = '' | |
user.posts.forEach(post => { | |
post.text = 'Test' | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment