Typescript: Tak dapat menetapkan nilai yang kompatibel ke properti jenis umum menggunakan `extends` dalam definisi umum.

Dibuat pada 7 Apr 2017  ·  3Komentar  ·  Sumber: microsoft/TypeScript

TypeScript Version: 2.2.2

Saya mungkin saja salah paham tentang cara kerja obat generik (jika demikian, tolong arahkan saya ke arah yang benar), tetapi ini sepertinya bug.

Kode

// A *self-contained* demonstration of the problem follows...

interface BaseState {
    on: boolean;
};

class Component {
    state: BaseState;

    setState(state: BaseState) {
        this.state = state;
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // no error
    }
}

class GenericComponent<State extends BaseState> {
    state: State;

    setState(state: State) {
        this.state = state
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // error Argument of type '{ on: boolean; }' is not assignable to parameter of type 'State'.
    }
}

Perilaku yang diharapkan:
Dalam kelas Component pada contoh di atas tidak menyebabkan kesalahan saat menggunakan antarmuka BaseState secara langsung. Saya mengharapkan perilaku yang sama dari kelas GenericComponent karena State generik secara eksplisit memperluas BaseState .

Perilaku sebenarnya:
Sebaliknya saya mendapatkan kesalahan berikut terkait dengan this.setState({ on: value > 0 }); : "Argumen tipe '{on: boolean;}' tidak dapat dialihkan ke parameter tipe 'Status'."

Question

Komentar yang paling membantu

Pertimbangkan apa yang terjadi jika Anda menulis ini

var t = new GenericComponent<{on: boolean, thing: string}>();
t.onInput({ value: 30 });
t.state.thing.substr(0); // 'thing' property should exist, but doesn't

Semua 3 komentar

Pertimbangkan apa yang terjadi jika Anda menulis ini

var t = new GenericComponent<{on: boolean, thing: string}>();
t.onInput({ value: 30 });
t.state.thing.substr(0); // 'thing' property should exist, but doesn't

Berikut adalah contoh yang disederhanakan:

class Stateful<State extends { on: boolean }> {
  state: State = {
    on: true
  }; // error
}

Alasan ini tidak berhasil adalah karena ini hanya akan valid ketika Stateful dibuat dengan argumen tipe yang sama persis dengan { on: boolean } .

Pada dasarnya, _ terdapat_ tipe T , memenuhi batasan dari argumen tipe Stateful sedemikian rupa sehingga instansiasi valid tetapi ini tidak berlaku _untuk semua_ tipe T dimana T memenuhi batasan dari argumen tipe Stateful .

Jadi kode yang salah di atas menegaskan bahwa, untuk semua jenis T<T> mana T, Stateful`.

Logikanya, kita bisa melihatnya sebagai berikut

Tuntutan

  1. Misalkan P menjadi tipe { on: boolean }
  2. Untuk semua jenis T sehingga T dapat dialihkan ke P , definisi Stateful<T> atas berlaku

Disproof dengan contoh counter

  1. Misalkan U menjadi tipe { on: boolean, value: number }
  2. U dapat dialihkan ke P -> menurut definisi
  3. Stateful<U> tidak valid -> dengan substitusi
  4. Oleh karena itu, ada tipe T sehingga T dapat dialihkan ke P dan Stateful<T> adalah contoh yang tidak valid -> implikasinya

@RyanCavanaugh @aluanhaddad Tembak, aku tahu itu. Saya baru saja bingung saat mencoba menyaring masalah menjadi sesuatu yang lebih sederhana. Jadi, coba lagi. Bagaimana jika dalam kasus ini menggunakan Partial? Saya masih mendapatkan kesalahan serupa.

interface BaseState {
    on: boolean;
};

class Component {
    state: BaseState;

    setState(partialState: Partial<BaseState>) {
        this.state = { ...this.state, ...partialState };
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // no error
    }
}

class GenericComponent<State extends BaseState> {
    state: State;

    setState(partialState: Partial<State>) {
        this.state = { ...this.state, ...partialState };
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // error: Argument of type '{ on: boolean; }' is not assignable to parameter of type 'Partial<State>'
    }
}
Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

Antony-Jones picture Antony-Jones  ·  3Komentar

remojansen picture remojansen  ·  3Komentar

DanielRosenwasser picture DanielRosenwasser  ·  3Komentar

uber5001 picture uber5001  ·  3Komentar

blendsdk picture blendsdk  ·  3Komentar