Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of an Interface with an "anonymous" method

Tags:

typescript

Given the following interface Fn,

interface Fn<A> {
    (): A
}

it is possible to instantiate an object implementing the interface using the builder

function buildFn<A>( val: A ): Fn<A> {
    return () => { return val }
}

Now, using the following interface which is valid in Typescript

interface FnString extends Fn<string> {
    (): string
    toLowerCase(): string
}

how do I write a builder function to instantiate an object implementing FnString ?

edit: solution thanks to @basarat

note:refactored String -> string according to comment

function builderFn(str: string): FnString {
    var fn = <FnString>(() => str)
    fn.toLowerCase = str.toLowerCase
    return fn
}
like image 454
Bruno Grieder Avatar asked Oct 19 '22 11:10

Bruno Grieder


1 Answers

If you want to create an object that is callable and has other functionality, the best way to do it is by starting with a function object. However since the native inferred type of the function does not match the actual type you are building to, you need a type assertion:

interface Fn<A> {
    (): A
}

function buildFn<A>( val: A ): Fn<A> {
    return () => { return val }
}

export interface FnString extends Fn<string> {
    (): string
    toLowerCase(): string
}

interface Awesome extends FnString { }
export function builderFn(): Awesome {
    var str = ('asdf'); 
    var fn = <Awesome>(() => str);
    fn.toLowerCase = str.toLowerCase;
    return fn;
}

Also note that string is not the same as String and String is an antipattern (hence I refactored to string).

like image 91
basarat Avatar answered Oct 22 '22 03:10

basarat