typescript - De ce nu mă protejează interfața în acest caz?


interface IA {
    readonly a: string;
    f(x: string): void;
}

class X implements IA {
    a;
    f(x) {
        this.a = 1;
    }
}

let x = new X().a;

Surprinzător, acest cod se compilează.

  • Inferă tipul lui X.a ca any, de ce se întâmplă asta?
  • readonly nu pare să mă protejeze de modificarea lui a. O fi folosit greșit?

Actualizare

https://github.com/Microsoft/TypeScript/issues/11578

Răspuns #1

Cam totul se reduce la faptul că orice variabilă ne-typed este implicit any. Poți dezactiva asta în opțiunile compilatorului:

  "noImplicitAny": true

moment în care va trebui să definiți un tip care poate fi atribuit tipului de interfață de bază.

în ceea ce privește modul doar citire. funcționează conform intenției:

trebuie să înțelegi că există unele diferențe între TypeScript și alte limbaje OO precum C#. Mai exact, atribuirii unei variabile tipizate alteia i se referă în totalitate dacă tipul din partea dreaptă se intersectează cu tipul din partea stângă. adică

let x: X = { a: "hello", f: (x) => { } };

este perfect valabil.

Răspunsul #2

Acesta deduce X.a ca fiind de tip any deoarece nu ai specificat tipul.
Când clasa ta implementează o interfață, trebuie apoi să specifici tot ce a definit interfața, dacă nu vei include membrul a:

class X implements IA {
    f(x) {
        this.a = 3;
    }
}

Vei primi:

Clasa 'X' implementează incorect interfața 'IA'.
Proprietatea 'a' lipsește în tipul 'X'

Și

Proprietatea 'a' nu există pe tipul 'X'

Nu primești erori pentru că nu ai inclus tipul pentru a, și asta pentru că este automat any și asta satisfice compilatorul.
Poți spune compilatorului să verifice acest lucru folosind noImplicitAny în opțiunile compilatorului:

Generați eroare pentru expresii și declarații cu un tip „any” implicit

Partea readonly nu este aplicată deoarece este doar readonly în interfața IA, dar nu și pentru clasă:

class X implements IA {
    a;
    f(x) {
        (this as IA).a = ""; // Error: Left-hand side of assignment expression cannot be a constant or a read-only property
    }
}

Și :

class X implements IA {
    readonly a;
    f(x) {
        this.a = ""; // Error: Left-hand side of assignment expression cannot be a constant or a read-only property
    }
}