1

Let's say I want to create an interface that looks like this:

interface DataStatus<T> {
   isSuccess: boolean; 
   isError: boolean;
   data: T | undefined; 
}

And later on I'm going to be using this like:

interface Foo {
   id: string; 
   name: string; 
}

function fetchData() : DataStatus<Foo> {
   //implementation
}


const ds = fetchData(); 

if (ds.isSuccess) {
   console.log(ds.data.name); //TS Warning - ds.data might be undefined
}

What I'd like to do add some conditions to the DataStatus interface with these rules:

  • isSuccess and isError must be opposites
  • data will have value T if isSuccess is true, and be undefined if isSuccess is false

Is this kind of thing possible with typescript?

1 Answer 1

3

Yes, you can if you have a discriminated union.

interface ISuccessDataStatus<T> {
   isSuccess: true; 
   isError: false;
   data: T; 
}

interface IFailureDataStatus<T> {
   isSuccess: false; 
   isError: true;
   data: undefined; 
}


type PossibleStatus<T> = ISuccessDataStatus<T> | IFailureDataStatus<T>;


declare const hello: PossibleStatus<{ name: "john" }>

if (hello.isSuccess) {
    const whatType = hello.data; // T and not T | undefined
}

const whatType = hello; // PossibleDataStatus; (outside the if block)

Typescript is smart enough to figure out when hello.isSuccess is true inside that block where it knows it's true it will narrow down the type of hello to ISucessDataStatus instead of the union.

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

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.