Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to declare a variable with two types via typescript

I want to declare a variable with two types via ts.But the complier tips error. like this:

interface IAnyPropObject { 
    [name: string]: any;
}
let a: IAnyPropObject | ((str: string) => any);
a.B = "bbbbbbbb";//tips error
a("");//tips error

note:I don't want to use 'any' to declare.I just want to constraint the variable by this way only.Because of the code are so old and they are not TS code.

like image 846
Free Tears Avatar asked Jun 22 '17 02:06

Free Tears


People also ask

How do you declare a variable with two types TypeScript?

In TypeScript, a union type variable is a variable which can store multiple type of values (i.e. number, string etc). A union type allows us to define a variable with multiple types. The union type variables are defined using the pipe ( '|' ) symbol between the types. The union types help in some special situations.

Can a variable have multiple types TypeScript?

TypeScript has the ability to understand variables that can have multiple types. For example, here is some normal JavaScript code: This is allowed in TypeScript by default, because var y (by itself) gives y a type of any , meaning anything. So we can assign anything, for example value or object, to y .

Is it possible to combine types in TS?

TypeScript allows merging between multiple types such as interface with interface , enum with enum , namespace with namespace , etc.

How do you declare a union type variable in TypeScript?

TypeScript 1.4 gives programs the ability to combine one or two types. Union types are a powerful way to express a value that can be one of the several types. Two or more data types are combined using the pipe symbol (|) to denote a Union Type.


2 Answers

Brief explanation of Mixin vs Union types.

Union: Either this or that type, but not both.

interface A { [name: string]: any; }
interface B { (str: string): string; }
type UnionType = A | B;

Mixin: A mix of this and that type at the same time.

interface A { [name: string]: any; }
interface B { (str: string): string; }
type MixinType = A & B;

Your code would work if you use a Mixin type, if that is your intention. Variable a can have a mix of both types at the same time.

like image 175
EyuelDK Avatar answered Oct 25 '22 14:10

EyuelDK


If you use an OR type, that doesn't mean your object has two types at the same time, you have to test it and use the correct type with casting inside of the test.

See https://www.typescriptlang.org/docs/handbook/advanced-types.html

interface IAnyPropObject { [name: string]: any; }
type MyFunc = (str: string) => any;
let a: IAnyPropObject | ((str: string) => any);
if (a instanceof Function) {
     (<MyFunc>a)("hi"); //passing a number will throw an error
} else {
    (<IAnyPropObject>a).b = 'bbbbbbbb';
}

You could also create a custom type guard, it's explained in the documentation I linked to, then you would not have to cast it. There's a lot more to be said, I just scratched the surface since I'm answering from my phone, read the doc for all the details.

like image 33
Juan Mendes Avatar answered Oct 25 '22 12:10

Juan Mendes