1

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?

5
  • is competitor_type another variable? Commented Mar 14, 2019 at 20:43
  • yes, it is another variable Commented Mar 14, 2019 at 20:43
  • 1
    You cannot base a Type on the value of a variable. Commented Mar 14, 2019 at 20:44
  • You can do this: let locals: PlayerDto | TeamDto then have an if statement to check if the value is of a specific type if(locals instanceof PlayerDto) {} else if(locals instanceof TeamDto){} Commented Mar 14, 2019 at 20:45
  • That was what I was looking for!!!, thanks, please add it as answer and I will accept it. Commented Mar 14, 2019 at 20:46

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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
}

Comments

3

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.