Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: is not assignable to type error

I am new to using typescript with angular 2. I am using version 1 of angular 2-cli. When compiling, I get this error saying "is not assignable to type Assignment[]". I looked at the data types and it looks okay so far, but I am not sure what the error is exactly. Thanks for your help.

Here is a photo of the error from the console. enter image description here

data.ts file - these are two of the items that appear in the array

export const Assignments: Assignment[] = [
  {
    "a_type": "one",
    "a_title": "Assignment 1",
    "symbol": 1,
    "show": false,
    "tooltip": {
        "left": 82
    },
    "buttonPos":{
        "left": 130
    },
    "printTop": 0,
    "instructions": "Instructions here",
    "due_date": "sept-15.png",
    "percentage": "10.png",
    "taskA": {
        "name": "Option A",
        "a_title": "Task A",
        "information": "Instructions for task A",
        "selectA": true
    }
}, {
    "a_type": "two",
    "a_title": "Assignment 2",
    "symbol": 2,
    "show": false,
    "sub_a_title": "Assignment Information",
    "tooltip": {
        "left": 200
    },
    "buttonPos":{
        "left": 250
    },
    "printTop": 250,
    "instructions": "Instructions here",
    "due_date": "29.png",
    "percentage": "10.png",
    "taskA": {
      "a_title": "Assignment 2 info",
        "name": "Option A",
        "information": "Instructions for task A",
        "selectA": false
    },
    "taskB": {
      "a_title": "Assignment 2 info",
        "name": "Option B",
        "information": "Instructions for task B",
        "selectB": false
    }
}
]

assignment.ts - here's the data types

export class Assignment {
    a_type: string;
    a_title: string;
    symbol: any;
    show: boolean;
    tooltip: any;
    left: number;
    buttonPos:any;
    printTop: number;
    instructions: string;
    due_date: string;
    percentage: string;
    taskA: any;
    name: string;
    information: string;
    selectA: boolean;
    taskB: any;
    selectB: boolean;
  }
like image 633
LadyT Avatar asked Oct 16 '16 17:10

LadyT


People also ask

How do I fix type null is not assignable to type string?

The "Type 'string | null' is not assignable to type string" error occurs when a possibly null value is assigned to something that expects a string . To solve the error, use a non-null assertion or a type guard to verify the value is a string before the assignment.

How do you fix type unknown is not assignable to type?

To solve the "Type 'unknown' is not assignable to type" TypeScript error, use a type assertion or a type guard to verify that the two values have compatible types before the assignment. The error is caused when a value of type unknown is assigned to a value that expects a different type.

How do I fix type string is not assignable to type never?

The error "Type is not assignable to type 'never'" occurs when we declare an empty array without explicitly typing it and attempt to mutate the array. To solve the error, explicitly type the empty array, e.g. const arr: string[] = []; .

Is not assignable to parameter of type string?

The error "Argument of type string | undefined is not assignable to parameter of type string" occurs when a possibly undefined value is passed to a function that expects a string . To solve the error, use a type guard to verify the value is a string before passing it to the function.


2 Answers

It's because the structure of the object literals don't match the Assignment structure.

Typescript is a structurally typed language, which means that a class' type and properties are defined by its structure. An object literal can be considered a type of a class if the structure maches. For example, say we have this class

class Person {
  firstName: string;
  lastName: string;
}

Instead of the normal way on instantiating a class with the new keyword,

let person: Person = new Person();
person.firstName = "Stack";
person.lastName = "Overflow";

we could use the following:

let person: Person = {
  firstName: "Stack",
  lastName: "Overflow"
}

If we didn't include the lastName property, we would get a compile error as the structure does not match that of the Person class and we tried to type it as a Person.

As far as your code, a few things I see wrong are:

  1. You're missing name and information because they are nested in the typeA. This doesn't work as they need to be in the main structure, as that is what is defined in Assignment

  2. You need taskB in the first object

  3. You're missing selectA and selectB from the main structure of the objects.

There are probably more errors also, but hopefully you get the point

If you want to make things optional, you can use the ? operator

interface Assignment {
  name?: string;
}

If you want nesting you can do that too

interface Assignment {
  taskA?: { name: string },
  taskB?: { name: string }
}

See also:

  • TypeScript docs on Type Compatibility
  • TypeScript docs in Interfaces
like image 92
Paul Samsotha Avatar answered Sep 22 '22 07:09

Paul Samsotha


The error is pretty clear:

Property 'left' is missing ...

Your Assignment class declares a member named left but both of your json objects don't have it.
You have a few more properties you haven't set in your json objects, here's a working version in playground.

You can declare the properties is optional if you want:

class Assignment {
    a_type?: string;
    ...
}

But even without the errors, you have a problem.
You're not creating instances of the class Assignment, you only create objects that match the class properties.
It works because typescript is using duck typing, but if you'll have methods in the Assignment then your objects won't have those.
You can do this:

export const Assignments: Assignment[] = [new Assignment(), new Assignment()];

Object.assign(Assignments[0], FIRST_JSON_OBJ);
Object.assign(Assignments[1], SECOND_JSON_OBJ);

Or you can have a constructor in Assignment who receives this json object and intialize itself.

like image 44
Nitzan Tomer Avatar answered Sep 25 '22 07:09

Nitzan Tomer