Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining TypeScript variable type function or string

I have this interface:

interface IParameters {
    form: number;
    field: string;
    ...
}

I want the formproperty to be number or function and field to be string or function.

I try something like this:

interface IParameters {
    form: number | Function;
    field: string | Function;
    ...
}

I need this because in my code i use this variables like this:

var form = (typeof _oParameters.form === "function" ? _oParameters.form() : _oParameters.form);
var field = (typeof _oParameters.field === "function" ? _oParameters.field() : _oParameters.field);

I don't want change this variable in all my code from string/number to default function and to prevent setting this variables to other types.

but if I try to call one of this two variable like function:

var param:IParameters;
param.form();
...

I get this error:

Cannot invoke an expression whose type lacks a call signature.

but param.form = 12; works.

The only solution that i have found is to declare form and field to any type.

Is other way to define this variable without any type?

like image 883
TotPeRo Avatar asked Mar 29 '16 14:03

TotPeRo


People also ask

How do you define a type variable in TypeScript?

The type syntax for declaring a variable in TypeScript is to include a colon (:) after the variable name, followed by its type. Just as in JavaScript, we use the var keyword to declare a variable. Declare its type and value in one statement.

How do you check if a variable is type string in TypeScript?

Use the typeof operator to check the type of a variable in TypeScript, e.g. if (typeof myVar === 'string') {} . The typeof operator returns a string that indicates the type of the value and can be used as a type guard in TypeScript.

Does TypeScript have a function type?

Types of Functions in TypeScript: There are two types of functions in TypeScript: Named Function. Anonymous Function.

Should you type everything in TypeScript?

Yes, you should make it a habit to explicitly set all types, it's will prevent having unexpected values and also good for readability.


2 Answers

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();
        }
    }
like image 65
NielsNet Avatar answered Oct 24 '22 23:10

NielsNet


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);
like image 27
Li0liQ Avatar answered Oct 24 '22 22:10

Li0liQ