Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.7k views
in Technique[技术] by (71.8m points)

Restrictions on number using typescript

I'm trying to define a type/interface (don't care which for the purpose of this exercise) that uses generics that has two properties:

interface Response<T> {
  status: number;
  data: T | undefined;
}

The restriction I want to capture is that when status !== 200, data must be undefined. When status === 200, data must be T. This way, I don't always have to check to see if response.data is not undefined after I check to make sure response.status is 200:

if (response.status === 200 && response.data) {
  // Wouldn't it be nice it TS just knew that response.data is
  // not undefined without having to check it explicitly?
}

So far, I have this:

interface IOkResponse<T> {
  status: 200;
  data: T;
}

interface IErrorResponse {
  status: number;
  data: undefined;
}

type Response<T> = IOkResponse<T> | IErrorResponse;

Of course, since IErrorResponse does not restrict status to numbers that are not 200, this doesn't work. How would I go about adding that restriction?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I agree with @jcalz, there is no hacky way to do it. One thing you cand do is typeguards. It will provide to your code type safety but you should pay for it - function overhead.


interface IOkResponse<T> {
  status: 200;
  data: T;
}

interface IErrorResponse {
  status: number;
  data: undefined
}

type Result<T> = IOkResponse<T> | IErrorResponse;

const isOK = <T,>(arg: Result<T>): arg is IOkResponse<T> => arg.status === 200

const foo = <T,>(arg: Result<T>) => {
  if (isOK(arg)) {
    const y = arg //  IOkResponse<T> 
  } else {
    const z = arg // IErrorResponse;
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...