node.js - 'T' kunne blitt instansiert med en vilkårlig type som kunne være urelatert


Jeg må gjøre en øvelse med datastrukturer, spesifikt med en dobbelt lenket liste, og jeg forstår ikke hvorfor jeg får denne feilen når jeg prøver å legge til to objekter i listen:

Argument av typen '{ id_user: number; id_touristic_place: number; review_title: string; review_desc: string; review_points: number; }' kan ikke tilordnes til parameter av typen 'T'. 'T' kan bli instansiert med en vilkårlig type som kan være urelatert til '{ id_user: number; id_touristic_place: number; review_title: string; review_desc: string; review_points: number; }'.ts(2345)

Jeg prøvde dette fra dokumentasjonen til TS

public addAtEnd<T>(data: T): void

men det gir meg en annen feil relatert til noden

Jeg vil sette pris på om du kunne prøve å forklare meg grunnen til feilen. (Jeg er ny på TS)

Her er koden min:

export class Node<T> {
  public data: T;
  public next: Node<T> | null;
  public prev: Node<T> | null;

  constructor(data: T) {
    this.data = data;
    this.next = null;
    this.prev = null;
  }
}

import { Node } from "./Node";
import { ILinkedList } from "./ILinkedList";

export class LinkedList<T> implements ILinkedList<T> {
  private head: Node<T> | null;

  constructor() {
    this.head = null;
  }

  public get gethead(): Node<T> | null {
    return this.head;
  }

  public set sethead(head: Node<T>) {
    this.head = head;
  }

  public addAtEnd(data: T): void {
    const newNode = new Node(data);
    if (!this.head) {
      this.head = newNode;
    } else {
      const getLast = (node: Node<T>): Node<T> => {
        return node.next ? getLast(node.next) : node;
      };

      const lastNode = getLast(this.head);
      newNode.prev = lastNode;
      lastNode.next = newNode;
    }
  }

  public addTwo(): void {
    this.addAtEnd({
      id_user: 1,
      id_touristic_place: 11,
      review_title: "Nice place",
      review_desc: "C:",
      review_points: 0,
    });

    this.addAtEnd({
      id_user: 2,
      id_touristic_place: 11,
      review_title: "Good",
      review_desc: "Not bad at all  ",
      review_points: 0,
    });
  }
}

Svar #1

Din LinkedList-klasse er generisk, noe som betyr at du ikke kan anta at den holder noen spesifikk type data.

Hvis du vil lagre en type data i en liste, f.eks. Users, må du spesifisere den typen. Dette gjøres vanligvis ved å konstruere en instans av LinkedList<User>.

Du kan også opprette en klasse ListOfUsers extends LinkedList<User>, men dette ville bare være nyttig hvis det finnes funksjonalitet som gjelder for en liste over brukere, men som ikke gjelder for lister av andre datatyper.

For eksempel:

export class LinkedList<T> implements ILinkedList<T> {
  private head: Node<T> | null;

  constructor() {
    this.head = null;
  }

  public get gethead(): Node<T> | null {
    return this.head;
  }

  public set sethead(head: Node<T>) {
    this.head = head;
  }

  public addAtEnd(data: T): void {
    const newNode = new Node(data);
    if (!this.head) {
      this.head = newNode;
    } else {
      const getLast = (node: Node<T>): Node<T> => {
        return node.next ? getLast(node.next) : node;
      };

      const lastNode = getLast(this.head);
      newNode.prev = lastNode;
      lastNode.next = newNode;
    }
  }
}

interface User {
      id_user: number;
      id_touristic_place: number;
      review_title: string;
      review_desc: string;
      review_points: number;
};

const myList = new LinkedList<User>();
myList.addAtEnd({
  id_user: 1,
  id_touristic_place: 11,
  review_title: "Nice place",
  review_desc: "C:",
  review_points: 0,
});
myList.addAtEnd({
  id_user: 2,
  id_touristic_place: 11,
  review_title: "Good",
  review_desc: "Not bad at all  ",
  review_points: 0,
});

Svar #2

Det forteller deg at objektet du sender inn på denne linjen ikke kan oppfylle hver mulig type T.

this.addAtEnd({
  id_user: 1,
  id_touristic_place: 11,
  review_title: "Nice place",
  review_desc: "C:",
  review_points: 0,
});

Som en av de uendelige mulighetene, hvis T er number, så vil det bare være lovlig å sende inn en number (som i this.addAtEnd(4)), men koden din sender ikke inn en number.

Hensikten med en generisk er at koden din fungerer med enhver type, og som et resultat kan du ikke gjøre noen antakelser om den typen, med mindre du legger til begrensninger for den. For addTwo-funksjonen din vil du ikke kunne lage et ad hoc-objekt som matcher hver mulig T, så det eneste praktiske du kan gjøre, er å la den ta imot data som argumenter. Med det kan den som bruker denne klassen, tilføye data av den typen de har i tankene.

public addTwo(first: T, second: T): void {
  this.addAtEnd(first);
  this.addAtEnd(second);
}

Relaterte artikler