TypeScript: Kan inte förstå detta fel: Typ: Foo saknar följande egenskaper från typ Bar add, addAll, delete, keys och 3 till


Jag har ett gränssnitt

interface Cache {
  a: {
    b: {
      c: string[];
      d: string;
    };
  };
}

Jag vill använda den för att skriva detta objekt

const cache: Cache = {
  a: {
    b: { c: ["stuff1", "stuff2", "stuff3", "stuff4"], d: "irrelevant" }
  }
};

Men jag kommer att få den här typen av fel

Typen '{ a: { b: { c: string[]; d: string; }; }; }' saknar följande egenskaper från typen 'Cache': add, addAll, delete, keys och 3 till.ts(2740)

Jag kan arbeta runt detta genom att typomvandla som

const cache = {
  a: {
    b: { c: ["stuff1", "stuff2", "stuff3", "stuff4"], d: "irrelevant" }
  }
} as Cache

Men jag förstår fortfarande inte varför jag skulle få det felet.

Också om jag upptäckte att om jag använder type istället för interface

type Cache2 = {
  a: {
    b: {
      c: string[];
      d: string;
    };
  };
};

const cache2: Cache2 = {
  a: {
    b: { c: ["stuff1", "stuff2", "stuff3", "stuff4"], d: "irrelevant" }
  }
};

Det finns inget typfel längre. Kan någon förklara anledningen för mig?

Live-demo: https://codesandbox.io/s/cache-type-o0cip?file=/src/index.ts

Svar #1

Detta är en namnkonflikt. Det finns redan ett gränssnitt som heter Cache i den globala kontexten för att stödja Cache Web API. På grund av deklarationssammanslagning, om du deklarerar ditt eget interface Cache {} i globalt omfång, lägger du bara till egenskaper/metoder till det. Detta är inte vad du vill göra.

Du bör antingen byta namn på Cache till något som MyCache,

interface MyCache {
  a: {
    b: {
      c: string[];
      d: string;
    };
  };
}

const myCache: MyCache = {
  a: {
    b: { c: ["stuff1", "stuff2", "stuff3", "stuff4"], d: "irrelevant" }
  }
};

eller så bör du deklarera det i ett annat omfång, som ett namespace

namespace MyNamespace {
  interface Cache {
    a: {
      b: {
        c: string[];
        d: string;
      };
    };
  }

  const cache: Cache = {
    a: {
      b: { c: ["stuff1", "stuff2", "stuff3", "stuff4"], d: "irrelevant" }
    }
  };
}

eller en modul (vilket kan indikeras genom att exportera något i din ts-fil):

export interface Cache {
  a: {
    b: {
      c: string[];
      d: string;
    };
  };
}

Lekplatslänk till kod

Svar #2

Det finns ett annat Cache-gränssnitt definierat i Typescript-biblioteket lib.dom.d.ts

interface Cache {
    add(request: RequestInfo): Promise<void>;
    addAll(requests: RequestInfo[]): Promise<void>;
    delete(request: RequestInfo, options?: CacheQueryOptions): Promise<boolean>;
    keys(request?: RequestInfo, options?: CacheQueryOptions): Promise<ReadonlyArray<Request>>;
    match(request: RequestInfo, options?: CacheQueryOptions): Promise<Response | undefined>;
    matchAll(request?: RequestInfo, options?: CacheQueryOptions): Promise<ReadonlyArray<Response>>;
    put(request: RequestInfo, response: Response): Promise<void>;
}

Så när du const cache: Cache={ tror det att du försöker använda gränssnittet ovan, därför fungerar det att ändra namnet till Cache2.