Skip to content

Instantly share code, notes, and snippets.

@Himenon
Last active May 10, 2019 09:50
Show Gist options
  • Save Himenon/15f59f7615318e5cd8bb87d698b9f16e to your computer and use it in GitHub Desktop.
Save Himenon/15f59f7615318e5cd8bb87d698b9f16e to your computer and use it in GitHub Desktop.
Sample code that evolves in order of argument type.
// https://github.com/sindresorhus/type-fest/blob/master/source/omit.d.ts
type Omit<ObjectType, KeysType extends keyof ObjectType> = Pick<ObjectType, Exclude<keyof ObjectType, KeysType>>;
interface A1 {
type: "a1";
a1: string;
}
interface A2 extends Omit<A1, "type"> {
type: "a2";
a2: string;
}
interface A3 extends Omit<A2, "type"> {
type: "a3";
a3: string;
}
interface A4 extends Omit<A3, "type"> {
type: "a4";
a4: string;
}
type InputSources = A1 | A2 | A3 | A4;
type EvoluteArgument<T> = T extends A1 ? A2 : never | T extends A2 ? A3 : never | T extends A3 ? A4 : never;
type EvoluteFunction<T = InputSources> = (value: T) => EvoluteFunction<EvoluteArgument<T>>;
export class EvolutionClass<T = InputSources> {
public use(args: T): this is EvolutionClass<EvoluteArgument<T>> {
return true;
}
}
const instance = new EvolutionClass();
const result =
instance.use({ type: "a1", a1: "a" }) &&
instance.use({ type: "a2", a1: "a", a2: "b" }) &&
instance.use({ type: "a3", a1: "a", a2: "b", a3: "c" });
const evolutionFunction: EvoluteFunction = <T extends InputSources>(value: T): EvoluteFunction<EvoluteArgument<T>> => {
return evolutionFunction;
};
evolutionFunction({ type: "a1", a1: "" })({ type: "a2", a1: "a", a2: "a" })({
type: "a3",
a1: "a",
a2: "a2",
a3: "a3",
})({ type: "a4" });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment