Home > Net >  Typescript treating a object literal as a contract interface / type
Typescript treating a object literal as a contract interface / type

Time:11-16

I'm writing a test where I'm creating an object literal. For example:

const myObject = {
  id: 1,
  name: 'egg',
  error: null
}

The initialised value for myObject.error is null. However, when I try set it to a new value later on. For example:

myObject.error = ['exception', 'mapping']

I assign it a new value of string[] but I get an error:

Type 'string[]' is not assignable to type 'null'.ts(2322)

myObject is not an interface or a type so why does it expect it to always be a null value?

Thanks!

CodePudding user response:

That happens because you didn't specifically define any other type for the myObject const, which will lead to TypeScript assigning the following type definition by default:

const myObject: {
    id: number;
    name: string;
    error: null;
}

Yeah, null is a TypeScript type, and obviously, string[] is not compatibale with that. You can however, define the type yourself, and make it compatible like so:

type ObjectType = {
    id: number;
    name: string;
    error: null | string[];
}

const myObject: ObjectType = {
  id: 1,
  name: 'egg',
  error: null
}

myObject.error = ['exception', 'mapping']

This way, you are letting TypeScript know, that myObject.error can either assume the null or string[] type values.

CodePudding user response:

TypeScript infers (guesses) the type of myObject, in your case it's:

{
    id: number;
    name: string;
    error: null;
}

When you try to assign to error it fails as it's expecting null. You could create an interface:

interface Produce {
    id: number;
    name: string;
    error: string[] | null;
}

const myObject: Produce = {
  id: 1,
  name: 'egg',
  error: null
};

myObject.error = ['a']; // <== This works

Regarding the usage of null, you could use an optional T? instead, which is equivalent to T | undefined:

interface Produce {
    id: number;
    name: string;
    error?: string[];
}

const myObject: Produce = {
  id: 1,
  name: 'egg'
};
  • Related