Defining TypeScript variable type function or string Defining TypeScript variable type function or string typescript typescript

Defining TypeScript variable type function or string


If you try to use the code from seriesOne you will notice, that you cannot assign form (or field) a value that isn't a function.You would get a
Type '{ form: string; }' is not assignable to type 'IParameters'. Types of property 'form' are incompatible. Type 'string' is not assignable to type '() => string'.

I found that using form: (() => string) | string; resolves this problem.

You can try the code at the typescript playground.

Working sample:

    interface IParameters {        form: (() => string) | string;    }    function strFunct(): string {        return 'Hello TypeScript';    }    function test() {        let paramA: IParameters = {            form: strFunct        }        let paramB: IParameters = {            form: 'Hello stackoverflow'        }    }    class Foo {        constructor(param: IParameters) {            var x = typeof param.form === 'string' ? param.form : param.form();        }    }


Perhaps if you define your union type using a call signature rather than Function, like so...

interface IParameters {    // form is of type function that returns number, or number literal.    form: () => number | number;    // field is of type function that returns a string, or string literal.    field: () => string | string;}class Foo {    constructor (param: IParameters) {        var x = typeof param.form === "number" ? param.form : param.form();        var y = typeof param.field === "string" ? param.field : param.field();    }}

Here, I am still checking form and field using typeof, however TypeScript is happy for it to be either a function call, or a value.


Upd
That behavior appears to be an issue #3812 with TypeScript.
It is to be fixed as a part of TypeScript 2.0 according to the milestone assigned.

Original answer

You could use instanceof as a type guard like

var field = (_oParameters.field instanceof Function ? _oParameters.field() : _oParameters.field);