Home > database >  Why does typescript allow storing incompatible object types from an API response?
Why does typescript allow storing incompatible object types from an API response?

Time:11-10

I am trying to get the data from an API endpoint using the following block of code.

interface IResponse{
  "id": number,
  "title": string,
  "description": string,
  "price": number,
  "discountPercentage": number,
  "rating": number,
  "stock": number,
  "brand": string,
  "category": string,
  "thumbnail": string,
  "images": Set<string>
}
fetch('https://dummyjson.com/products/1')
    .then(res => res.json())
    .then(res => {
        let b: IResponse = res;
        console.log(b)

    });

As you can see, the type of images in IResponse is a set of strings. However, the API response returns an array of images, and I am assigning that response object to a variable with type IResponse. So the question is, why doesn't typescript complain about type mismatch of images property in response object(array) and IResponse interface (set of Strings) upon assignment?

CodePudding user response:

TypeScript types are not available at runtime as TypeScript code is transpiled to JavaScript which has no concept of types. Your API call however happens at runtime when there are no types available. JSON.parse() returns any as far as TypeScript is concerned therefore there's no error.

If you want to make sure your JSON conforms to a certain structure you can use JSON Schema. A popular library to validate JSON using JSON Schema with TypeScript support is Ajv.

CodePudding user response:

In your code, res is of type any:

fetch('https://dummyjson.com/products/1')
    .then(res => res.json())
    .then(res => {
//        ^? any
        let b: IResponse = res;
        console.log(b)
    });

any is TypeScript's way to opt out of type-checking:

TypeScript also has a special type, any, that you can use whenever you don’t want a particular value to cause typechecking errors.

When a value is of type any, you can access any properties of it (which will in turn be of type any), call it like a function, assign it to (or from) a value of any type, or pretty much anything else that’s syntactically legal

As such, almost anything you do with it is allowed. You'll need to perform runtime validation on res if you want it to be correct at runtime.

  • Related