Eduardo
Eduardo

Reputation: 1831

Typescript: Setting variable type dynamically

I have 2 variables:

let locals 
let visitants

Each of them can be of type PlayerDto or TeamDto. Type will depend on third variable called competitor_type. If competitor_type is player then I would need to assign a list of Players to locals and visitants, other ways a list of teams.

I am solving it using "any"

locals: any
teams: any

Is there a better way of solving it?

Upvotes: 1

Views: 3448

Answers (3)

Jonas Wilms
Jonas Wilms

Reputation: 138537

You should wrap the different versions in an Object, to then be able to narrow down the types:

let state: {
  type: "player";
  locals: PlayerDto[] | undefined;
   visitants: PlayerDto[] | undefined;
} | {
  type: "team";
  locals: TeamDto[] | undefined;
  visitants: TeamDto[] | undefined;
} = { type: "player" };

Then your code is always typesafe:

 if(state.type === "player") {
   state.locals // is of type PlayerDto[]
 }

 state.locals // is of type PlayerDto[] | TeamDto[]

To change the type, do:

 state = { type: "team" };

then you can reassign state.locals and state.visitants.

Upvotes: 5

Get Off My Lawn
Get Off My Lawn

Reputation: 36351

You can not base a type on a variable, however you can list the types that a variable can be by using a union type (|) to list all the different types like this:

let locals: PlayerDto | TeamDto
let visitants: PlayerDto | TeamDto

Then when using this it is offten needed that you check the type by using an instanceof

if(locals instanceof PlayerDto) {
  // Do something for PlayerDto
}
else if(locals instanceof TeamDto) {
  // Do something for TeamDto
}

Upvotes: 3

Mariusz Pilarczyk
Mariusz Pilarczyk

Reputation: 518

You can use union type.

let locals: PlayerDto[] | TeamDto[];

Doing this you are saying that locals can be either list of PlayerDto or list of TeamDto.

More details on union and other advanced types here: https://www.typescriptlang.org/docs/handbook/advanced-types.html

Upvotes: 3

Related Questions