Skip to content

Instantly share code, notes, and snippets.

@kumatch
Last active May 18, 2021 08:49
Show Gist options
  • Save kumatch/500b1a2d3172cc4af72df10362474d88 to your computer and use it in GitHub Desktop.
Save kumatch/500b1a2d3172cc4af72df10362474d88 to your computer and use it in GitHub Desktop.
// https://www.typescriptlang.org/ja/play?#code/MYewdgzgLgBAllApgWwjAvDA2gKBjAb3gBMAuGARgoBoYwBDZRcgcgDMQQWBfavQkuQoAmWgyasARvQBOPHAF0cOYABt6ENAAVZiMLAL8ZiesXCqAniQD85MAFdkkxDIDcy-KEhQZ94FBAZAApZAHMIch0ZKDh6VQAeKL0oAD4ASkJ+fAB5SQArRH8AOg0IOFCwIKgACzgIWjCINPd8bnwPGGh6GOAYNjgwYniAFRhEAA8kQbQoCwAHRBA2GCT9GAAyATjVcgBJb3owYERh+cQRlKwFGG4UqtqImGHaODI6R2cZNL2Do5Ozi4wAA+MHsg0Q-TAiGImXw+GMUHsMjAMBqdRKqlURUhxCCKPQKToRVeGEwrzS-G4HS6PRgAHdqi5zqMJlNiDMzksVro1psiNsfl0-qcFhcrjc7mjHs8YHNZIxHgQsABrRAWcjQGQDUIKciHCzcb4wfZC44i5mXa6GOEwLzQGCqixoTC5ArFR0QIJymQKilZGAIpEoqUYrH9VRIYL4wnWm0BxCI5EOtUQIqIABuLgsQUdGBj-ptgaTYBVapgGmTFi5qyg13Q9dl8tQpYsSjjN2a-sNLRuHVCCfgEC0LjK0GhQSNkk4qhMKNj8ITQdRD2JMIAhA2wcQIQNoT2qVSVOpNMakMgxpM9OzucY1rHjKZzFZXmu7B8XD2H2YwJY6IxEK+nQ+Nq7j8HaPh+AEwSNJEsgxHE8S7Ge6SwnCED2As0EyOEnY2q6hRQCUmjlJUUoNNhTT7tSUDdHAvT9rA2wTqhhaLkmCAoKmyD0HMQQceeBJ0IgdKnigfFnmkuG9oe4HlhgonINiAy4lQnZ2iAM5FKoIChCEangBAGmIFpOkhNYxJDiOdRIMQ+mQEZJm6UhKBFAyTJBEQrxCKIf4SDALDSHIhqdsoOBAA
const items = [
{ id: 11, name: 'foo'},
{ id: 12, name: 'bar'}
]
class Parent {
readonly id?: number;
constructor(args: Partial<Parent>) {
Object.assign(this, args);
}
static find<T extends typeof Parent & { all: InstanceType<T>[] }>(this: T, id: number): InstanceType<T> | undefined {
return this.all.find(n => n.id == id)
}
static where<T extends typeof Parent & { all: InstanceType<T>[] }>(this: T, params: {[key: string]: any}): InstanceType<T>[] {
const keys = Object.keys(params)
return this.all.filter(n => {
return keys.every(key => {
return n[key as keyof Parent] === params[key]
});
});
}
get isPersisted(): boolean {
return this.id !== undefined;
}
}
class Item extends Parent {
readonly id!: number;
readonly name!: string;
constructor(args: Partial<Item>) {
super(args);
Object.assign(this, args);
}
static get all() {
return items.map(item => new Item(item));
}
}
const a = Item.find(11);
console.log(a);
console.log(a?.isPersisted);
console.log(Item.where({ id: 12, name: 'bar'}));
// https://www.typescriptlang.org/ja/play?#code/MYewdgzgLgBAllApgWwjAvDA2gKBjAb3gBMAuGARgoBoYwBDZRcgcgDMQQWBfavQkuQoAmWgyasARvQBOPHAF0cOKAE8ADohgBhcNBkBXYFBAyAPABUMhbgD5rYRAHcYACgB0n2QHMI5emCqWAoAlBj2FgDcymwGYMZw4DDIcAAecGAAoqmM6gA2iBCWAEL0EFqIqUhgxGi6kFCGxqZmRHDEAPzkYAbIkogyMHa2rqXl5BZjiGEE-DKIUAYyYDDAeWVoldW1MFOE-PjQ9FBwwDBsGcSWMFuINWiTZVoAZAL0eXnkAJINAcCIFg0iEstmCQxGUAAFnA-DALLR2t1ev0ZCFvr94gCgSCYAAfGBxYiIC6OYj7fAUmDzRbLGBQmHud55dwk4iuFboexgdztDDoTDtEIHIbKSlHE5nJyQgbAqy3e5wvavIhM9FHTGAzQgsF2Vz02HwmDqWSMWEELAAa0QqnI+gy3gU-kC3DRMB+6v+mtloIU5Mpqz0sCtqjQmAA8pIAFaIYzuYMQVzGmSmoXC-DUpYrfWMj4suB5JAydnhP3+qkLTMwePuRAANwGqlcwZLszLlIztLAlutMDKbmDIDYboxnuxFlsIV9-MwSdN3dUSjbQxC0TLLtXFO4oop3gW8AgAAUBhAYUg2a7JJwCgFSxSO1noRAeWSAIT8gk1YkZRDEDf4Lf-tEW44GsGxukgyB7K25b0MQ4B5KoJAvkifQDBu8ywfBiHiIgyEwHaYDeNE-CgA0TQmEWPiwgesgnO8ZhfBBUwTreEbRrGGxwN4YB6o+tBUSu-DAYcUDHKcMC7rATKuDMabljSKwICgT7IPQ6iuEpyAlo4LiMSgGkQSEgn-jgwGkdA4EoNYKTpFkOTIPkhSuHpkFPKm5lSdYLl5jUrhUIJ5kgAU7h5CA3iuPQAV6EFiAhWFEUdDyh7HqeP5RZAMVxeF3lSjKrhtGQlCiHQjDMDALDSHILqCUAA
const items = [
{ id: 11, name: 'foo'},
{ id: 12, name: 'bar'}
]
type Constructor<T = {}> = new (...args: any[]) => T;
function mixinExamples<TBase extends Constructor<{ id?: number }>>(Base: TBase) {
return class extends Base {
static find<T extends TBase & { all: InstanceType<T>[] }>(this: T, id: number): InstanceType<T> | undefined {
return this.all.find(n => n.id === id)
}
static where<T extends TBase & { all: InstanceType<T>[] }>(this: T, params: {[key: string]: any}): InstanceType<T>[] {
const keys = Object.keys(params)
return this.all.filter(n => {
return keys.every(key => {
return n[key as (keyof InstanceType<T>)] === params[key]
});
});
}
get isPersisted(): boolean {
return this.id !== undefined;
}
};
}
class ItemBase {
readonly id!: number;
readonly name!: string;
constructor(args: Partial<ItemBase>) {
Object.assign(this, args);
}
static get all() {
return items.map(item => new Item(item));
}
}
const Item = mixinExamples(ItemBase)
const a = Item.find(11);
console.log(a);
console.log(a?.isPersisted);
console.log(Item.where({ id: 12, name: 'bar'}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment