reactjs - Typescript cum să combini tipizarea dinamică ([key: type]: type) și tipizarea statică pentru o interfață
Problema principală
Nu sunt chiar sigur dacă acest lucru este posibil, dar fiindcă urăsc Typescript și îmi face codarea dificilă, m-am gândit să întreb doar ca să fiu sigur.
interface ISomeInterface {
handler: () => {}
[key: string]: string
}
Problema, evident, este că handler este un () => {} și nu un șir de caractere, așa că TypeScript aruncă o eroare. Este posibil cumva să facem să funcționeze asta?
Aditament :
Tot pe această temă, această interfață este destinată să fie utilizată de un React.Context și, deoarece React.createContext(/* necesită valoare implicită aici */) impune o valoare implicită, trebuie să îi ofer un obiect care să corespundă acelei interfețe. Când încerc să trec un literal de obiect astfel:
React.createContext({handler: () => {throw new Error('using default context')}})
Typescript face o zarvă spunând {handler:() => never} nu poate fi atribuit lui {handler:() => {}}. Există vreo modalitate de a face această interfață plauzibilă? Am încercat să fac ca interfața să implementeze () => any, dar tot nu a funcționat, vrea never explicit.
Editare #1:
Așa că am făcut câteva modificări, și anume:
interface IFormContext {
$handleChange: (key?, val?) => void
$registerField: (key?) => void
[key: string]: { value: string } | ((key?, val?) => void)
}
Dar acum, când încerc să accesez câmpul astfel: const {[key]: { value }}=props, care este practic destructurarea cu o cheie dinamică, primesc următoarea eroare:
Property 'value' does not exist on type '{ value: string; } | ((key?: any, val?: any) => void)'.ts(2339)
Răspuns #1
Din păcate, proprietățile tale denumite trebuie să corespundă semnăturii indexului. În acest caz, deoarece cel puțin o proprietate este o funcție, poți folosi:
[cheie: string]: string | Funcție;
sau
[key: string]: any;Ambele ar trebui să funcționeze.
Pentru adăugarea ta, () => {} înseamnă o funcție fără argumente care returnează un obiect gol, în timp ce funcția () => {throw new Error('using default context')} nu returnează nimic, de aceea apare eroarea. Există puțină confuzie legată de acoladele folosite în tipuri și în implementarea efectivă a funcției.
O funcție cu tipul () => {} este de fapt ceva de genul () => {return {}} sau () => ({}).
Pentru o funcție care nu returnează nimic, poți folosi never sau void, dar dacă handler-ul tău poate returna ceva, poți folosi ceva de genul handler:() => void | boolean, înlocuind boolean cu tipul pe care poate să-l returneze.