Skip to content

Instantly share code, notes, and snippets.

@achakravarty
Last active April 10, 2019 05:13
Show Gist options
  • Save achakravarty/4e4db263f3b16d780bd61a1bed8d2acd to your computer and use it in GitHub Desktop.
Save achakravarty/4e4db263f3b16d780bd61a1bed8d2acd to your computer and use it in GitHub Desktop.
Simple type inference for properties of an object
type Inferable<T, K extends keyof T> = T[K] extends Function ? T[K] : never;
function asInferable<T, K extends keyof T>(_: T, key: K): (fn: Inferable<T, K>) => void {
return function(fn: Inferable<T, K>) {
console.log(fn("world"));
};
}
class Foo {
bar(str: string): string {
return `hello ${str}`;
}
baz(num: number): number {
return 1 + num;
}
}
asInferable(new Foo(), "qux")(() => {}); // Argument of type '"baz"' is not assignable to parameter of type '"bar"'
asInferable(new Foo(), "bar")(() => {}); // Argument of type '() => void' is not assignable to parameter of type '(str: string) => string'
asInferable(new Foo(), "bar")((num: number) => 1 + number); // Argument of type '(num: number) => number' is not assignable to parameter of type '(str: string) => string'
asInferable(new Foo(), "baz")((str: string) => `Hola! ${str}`); // Argument of type '(str: string) => string' is not assignable to parameter of type '(num: number) => number'
asInferable(new Foo(), "bar")((str: string) => `Hola! ${str}`); // Works 👍
asInferable(new Foo(), "bar")(() => `Hola!`); // Also Works 👍
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment