Search code examples
typescript1.4

Union parameters with TypeScript 1.4


I have some troubles using union parameters. Imagine I have such a function:

interface IColumnDefinition {
    id: string;
    title: string;
}

addColumn(definition: string|IColumnDefinition) {
    if (typeof (definition) === "string") {
        definition = { id: definition, title: definition };
    }

    var column = new JSColumn(definition);
    ...
}

I want the user to either pass a complete object that defines a new column, or just pass a string, in which case I create a default object.

However, TypeScript has 2 problems:

  • definition = { id: definition }; is not allowed, since TypeScript thinks that definition might not be a string - which is wrong, since I make a typeof one line above.
  • new JSColumn(definition) is not possible, since the constructor requires a IColumnDefinition object, and definition could also be a string - which is also wrong, because the if above made sure that it is always a correct object.

What can I do to convince TypeScript that these are not errors? Is there anything like a cast, which says "Hey, this variable is of type xyz. Trust me, I know what I do."

I'm currently defining the parameter as any, which isn't really an option as I lose the whole advantage of type-checking.


Solution

  • If you want to circumvent the type system of TypeScript you can always use <any> cast.

    In this case however there's a better solution:

    function addColumn(definition: string | IColumnDefinition) {
        var colDef: IColumnDefinition;
        if (typeof definition === "string") {
            colDef = { id: definition, title: definition };
        } else {
            colDef = definition;
        }
    
        var column = new JSColumn(colDef);
        // ...
    }
    

    Another option, which might be less clear but generates a smaller JS code:

    function addColumn(definition: string | IColumnDefinition) {
        var column = new JSColumn(
            (typeof definition === "string")
                ? { id: definition, title: definition }
                : definition);
        // ...
    }