Skip to content

Instantly share code, notes, and snippets.

@ddprrt

ddprrt/broken.js Secret

Last active September 8, 2020 07:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ddprrt/8eee21d9680e1b978cbd88a080b57e63 to your computer and use it in GitHub Desktop.
Save ddprrt/8eee21d9680e1b978cbd88a080b57e63 to your computer and use it in GitHub Desktop.
TypeScript examples
const storage = {
max: undefined,
items: []
};
Object.defineProperty(storage, 'max', { readonly: true, val: 5000 });
let currentStorage = 'undefined';
function storageUsed() {
if (currentStorage) {
return currentStorage;
}
currentStorage = 0;
for (const i = 0; i < storage.length; i++) {
currentStorage += storage.items[i].weigth;
}
return currentStorage;
}
function add(item) {
if (storage.max - item.weight >= storageUsed) {
storage.items.add(item);
currentStorage += iten.weight;
}
}
function logMe(x: string): void {
console.log(x);
}
const whyDoesthisWork = logMe('hello')
declare function sjax() : number[];
function fetchResults(callback: (statusCode: number, results: number[]) => void) {
// get results from somewhere
const results:number[] = sjax()
callback(200, results);
}
function handler(status: number): boolean {
return true;
}
fetchResults(handler);
const A = {
x: 2,
y: 3,
};
function doSomething(b: (typeof A & { [key: string]: any })) {
// ...
}
doSomething({
x: 4,
y: 1,
z: 0
});
type PointT = {
x: number;
y: number;
}
interface PointI {
x: number;
y: number;
}
interface Shape {
area(): number;
}
type Perimeter = {
perimeter(): number;
}
type Name = { name: string };
type Id = { id: number };
type Check = { check: boolean };
type Label<T> =
T extends string ? Name :
T extends number ? Id :
T extends boolean ? Check :
never;
declare function createLabel<T extends string | number | boolean>(value: T): Label<T>;
createLabel(true)
type Tabs =
{ tabs: number } |
{
tabsEnum: {
[tabName: string]: string
}
}
type Compare =
{ compare: (v: boolean) => boolean } |
{ compareTo: boolean }
type MiniTabsProps = Tabs & Compare & {
allowNull: boolean
};
const props: MiniTabsProps = {
allowNull: true,
tabsEnum: {
'type': 'hard',
'with': 'a vengenance'
},
compareTo: true
}
const props2: MiniTabsProps = {
compareTo: true,
allowNull: true,
tabs: 1
}
const nonWorkingProps: MiniTabsProps = {
allowNull: false
}
function useMutationWithReset<
MutationVariables,
AddUserId extends boolean = false
// the "as any" is needed here because definite values can't be assigned to generics
>(mutation: string, { addUserId = false as any }: { addUserId?: AddUserId } = {}) {
type Variables = AddUserId extends true
? MutationVariables & { userId: string }
: MutationVariables & { userId?: string }
return {
mutate: async (variables: Variables) => {
// ...
}
}
}
const test = useMutationWithReset('', { addUserId: true })
test.mutate({}) // errors
const test2 = useMutationWithReset('', { addUserId: false })
test2.mutate({}) // passes
const test3 = useMutationWithReset('')
test2.mutate({}) // passes
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
type Optional<T> = { [K in keyof T]?: T[K] }
type GulpCbFn = (err?: string) => void;
type GulpReturnType<T> = T extends GulpCbFn ? void : Promise<any>;
type GulpTaskFn<T> = (done?: T) => GulpReturnType<T>;
interface Gulp {
task<T>(name: string, taskFn: GulpTaskFn<T>) :void;
}
declare const gulp: Gulp;
gulp.task('default', function(done: GulpCbFn) {
done()
})
type JSONified<T> =
JSONifiedValue<T extends { toJSON(): infer U } ? U : T>;
type JSONifiedValue<T> =
T extends string | number | boolean | null ? T :
T extends Function ? undefined :
T extends Array<infer U> ? JSONifiedArray<U> :
T extends object ? JSONifiedObject<T> :
undefined;
type UndefinedAsNull<T> = T extends undefined ? null : T;
interface JSONifiedArray<T> extends Array<UndefinedAsNull<JSONified<T>>> {}
type JSONifiedObject<T> = {
[P in keyof T]: JSONified<T[P]>
}
declare class Widget {
toJSON(): {
kind: "Widget", date: Date
}
}
type Item = {
text: string;
count: number;
choice: "yes" | "no" | null;
func: () => void;
nested: {
isSaved: boolean;
data: [1, undefined, 2];
}
widget: Widget;
children: Item[];
}
declare let item: JSONified<Item>;
export type ServiceDefinition = {
[x: string]: MethodDefinition;
};
export type MethodDefinition = {
[x: string]: StringConstructor | NumberConstructor;
};
export type ServiceObject<T extends ServiceDefinition> = {
[P in keyof T]: ServiceMethod<T[P]>
};
export type ServiceMethod<T extends MethodDefinition> = {} extends T
? () => boolean
: (payload: RequestPayload<T>) => boolean;
export type RequestPayload<T extends MethodDefinition> = {} extends T
? undefined
: { [P in keyof T]: TypeFromConstructor<T[P]> };
export type TypeFromConstructor<T> = T extends StringConstructor
? string
: T extends NumberConstructor ? number : any;
export type RequestHandler<T extends ServiceDefinition> = (req: RequestObject<T>) => boolean;
export type RequestObject<T extends ServiceDefinition> = {
[P in keyof T]: {
message: P;
payload: RequestPayload<T[P]>;
}
}[keyof T];
function createService<S extends ServiceDefinition>(
serviceDef: S,
handler: RequestHandler<S>,
): ServiceObject<S> {
const service = {} as any;
for (const name in serviceDef) {
service[name] = (payload: any) => handler({ message: name, payload });
}
return service as ServiceObject<S>;
}
const serviceDefinition = {
open: { filename: String },
insert: { pos: Number, text: String },
delete: { pos: Number, len: Number },
close: {},
};
const service = createService(serviceDefinition, req => {
switch (req.message) {
case 'open':
break;
case 'insert':
req.payload
break;
default:
req.
break;
}
return true;
});
service.close();
service.open({ filename: 'text.txt' });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment