Skip to content

Instantly share code, notes, and snippets.

@andrew8088
Created June 3, 2023 22:50
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save andrew8088/d15413b1e4a9125fa29cc65103d9c756 to your computer and use it in GitHub Desktop.
Save andrew8088/d15413b1e4a9125fa29cc65103d9c756 to your computer and use it in GitHub Desktop.
how i learn typescript
type Tables = {
person: {
id: number;
first_name: string;
},
product: {
id: string;
name: string;
createdAt: Date
}
};
type TableNames = keyof Tables;
type Alias<T extends string> = T extends `${string} as ${infer A}` ? A : never;
type Original<T extends string> = T extends `${infer O} as ${string}` ? O : never;
type SqlAlias<ColumnNames extends string> = ColumnNames extends ColumnNames ?
`${ColumnNames} as ${string}` :
never;
type Columns<ColumnNames extends string> = ColumnNames | SqlAlias<ColumnNames>;
type SelectReturn<
Name extends TableNames,
Column extends Columns<keyof Tables[Name] & string>
> = {
[C in Column as
Alias<C> extends never ?
C :
Alias<C>
]: C extends keyof Tables[Name] ?
Tables[Name][C] :
Original<C> extends keyof Tables[Name] ?
Tables[Name][Original<C>] :
never; // unreachable
}
declare function select<
Name extends TableNames,
Column extends Columns<keyof Tables[Name] & string>
>(tableName: Name, columns: Column[]):
SelectReturn<Name, Column>;
const person = select('person', ["first_name as firstName", "id"])
const product = select('product', ['createdAt', 'name as productName'])
type P1 = Flat<typeof person>;
type P2 = Flat<typeof product>;
type Flat<T> = {
[K in keyof T]: T[K];
}
@neerajkumar161
Copy link

Awesome, though I got only 70% of the codebase. 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment