Saya memiliki kode berikut:

type SuperType<T = any> = {
    entities?: {
        [key: string]: T
    };
}

class Test<T> {
    value: T;

    constructor(v: T) {
      this.value = v;
    }

    update(cb: (v: T) => T) {
      this.value = cb(this.value);
    }
}

interface H extends SuperType<{ prop: number }> {}

const instance = new Test<H>({});

Saya ingin membuat fungsi tingkat tinggi yang memperbarui nilai:

function updateSomething<
    T extends SuperType,
    E = T extends SuperType<infer I> ? I : never>(arg: E) {
    return function (value: T) {
       return value;
    }
}

Bagaimana saya bisa menyimpulkan tipe generik dalam fungsi tingkat tinggi?

instance.update(updateSomething(placeholder))

Jadi di sini placeholder harus diketik sebagai { prop: number }

0
undefined 11 Juli 2020, 22:52

1 menjawab

Jawaban Terbaik

Saya tidak melihat bagaimana SuperType terlibat sama sekali, karena H tidak dapat ditetapkan ke SuperType. Saya akan mengabaikan SuperType untuk saat ini dan Anda dapat memberi tahu saya jika pertanyaan Anda perlu diubah untuk memanfaatkannya.


Kecenderungan saya untuk mengetik updateProp() adalah sebagai berikut:

function updateProp<K extends PropertyKey>(prop: K) {
    return function <T extends Record<K, any>>(value: T) {
        return value;
    }
}

Di sini saya mengatakan bahwa K diizinkan untuk menjadi benda seperti kunci apa pun, dan kemudian fungsi yang dikembalikan akan menerima nilai apa pun dengan K sebagai kunci dan mengembalikan jenis benda yang sama. Ini memiliki efek yang diinginkan bila digunakan dengan instance.update():

instance.update(updateProp('name')); // okay
instance.update(updateProp('id')); // okay
instance.update(updateProp('notExists')); // error, as desired

Apakah itu berhasil untuk Anda? Semoga membantu; semoga berhasil!

Tautan taman bermain ke kode


MEMPERBARUI

Untuk contoh modifikasi Anda, saya telah mengubah pengetikan tetapi mempertahankan ide dasar yang sama: Anda perlu updateProp() menjadi generik dalam jenis argumennya, dan kemudian menghitung jenis lain darinya:

function updateProp<E>(prop: E) {
    return function <T extends SuperType<E>>(value: T) {
        return value;
    }
}
instance.update(updateProp({ prop: 123 })); // okay
instance.update(updateProp({ prop: "" })); // error
instance.update(updateProp({ prop: 123, unexpectedProp: 456 })); // error

Semoga membantu lagi; semoga berhasil.

Tautan taman bermain ke kode

1
jcalz 12 Juli 2020, 19:36