Last active
February 17, 2019 17:21
-
-
Save marcj/266394179d50dad98d7fe15ae93ae488 to your computer and use it in GitHub Desktop.
Typescript creating a new deep subtype based on runtime arguments.
This file contains 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
interface Writer { | |
id: number; | |
username: string; | |
notIncludedAsWell: string; | |
} | |
interface Post { | |
id: number; | |
content: string; | |
notIncluded: string; | |
writer: Writer | |
} | |
type Primitive = string | boolean | number | symbol; | |
type ValuesOf<T extends Primitive[]> = T[number]; | |
type PropertyNames<T> = { [K in keyof T]: T[K] extends Primitive ? K : never }[keyof T]; | |
type PickByArray<T, KW extends K[], K extends keyof T = any> = { | |
[P in ValuesOf<KW>]: T[P] | |
} | |
function Bla2< | |
ValidRootTypes extends keyof Post, | |
SecondLevelProperties extends {[PT in keyof Post]?: PropertyNames<Post[PT]>[]}, | |
SecondLevelProperties2 extends keyof SecondLevelProperties & keyof Post, | |
R = Pick<Post, ValidRootTypes> & {[PT in SecondLevelProperties2]: PickByArray<Post[PT], SecondLevelProperties[PT]>} | |
>(rootPropertyNames: ValidRootTypes[], secondLevelProperties: SecondLevelProperties): R { | |
return {} as R; | |
} | |
//this is what we expect | |
type expect = Pick<Post, 'id' | 'content'> & {writer: Pick<Post['writer'], 'id' | 'username'>}; | |
//this is what we actually get | |
const actual = Bla2(['id', 'content'], {writer: ['id', 'username']}); | |
actual.id; //number | |
actual. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
line 24 :
ValidRootTypes extends PropertyNames<Post>,
, To avoid input writer in root property names