javascript - Typescriptin valinta, D3.js-funktion ylikuormitus ja palautustyyppi
Työskentelen tällä hetkellä d3.js:n, Reactin ja Typescriptin kanssa, ja minulla on vaikeuksia ymmärtää paras tapa määrittää funktioylikuormitus manuaalisesti ja poistaa mahdollisuus saada undefined-paluuarvo.
Alla olevassa esimerkissä yritän käyttää ulottuvuutta ja palauttaa [Date, Date] käyttämällä seuraavan tyyppistä pääsyfunktiota.
xAccessor: (datum: Window, index: number, array: Iterable<Window>) => Date
Esimerkkikäyttö:
const xScale = d3.scaleTime()
.domain(d3.extent<Iterable<Window>, Iterable<Date>>(data, xAccessor))
.range([0, dimensions.boundedWidth])
Ongelmana on, että saan tämän virheilmoituksen
Argument of type '[string, string] | [undefined, undefined]' is not assignable to parameter of type 'Iterable<number | Date | { valueOf(): number; }>'.
Uskon, että tämä johtuu siitä, että DefinitelyTyped d3 -paketilla on seuraava määritelmä.
export function extent<T, U extends Numeric>(
iterable: Iterable<T>,
accessor: (datum: T, index: number, array: Iterable<T>) => U | undefined | null
): [U, U] | [undefined, undefined];
Huomaa, että Ikkuna-tyyppi ei salli määrittelemätöntä päivämäärää.
export interface Window {
ts: Date;
high: number;
low: number;
open: number;
close: number;
volume: number;
}
const dateAccessor = (d: Window) => d.ts
Olen nähnyt muita vastauksia kuten alla, joissa tarkistetaan määrittelemätön ja määritetään oletusarvo, mutta en ole varma, miten tehdä se ja silti hyödyntää propsien kautta lapseen komponenttiin välitettyä accessor-funktiota.
React, Typescript, d3js, Saadaan virhe 'No overload matches this call'
Onko olemassa oikeaa tapaa pakottaa tietty ylikuormitus ja samalla poistaa mahdollisuus määrittelemättömään tulokseen käytettäessä accessor-metodia, joka annetaan osana propsia?
Vastaus #1
Olen kohdannut samanlaisen ongelman samanlaisella koodilla, ja näin korjasin sen:
interface Entry {
time: Date
}
x.domain(d3.extent(entries, (e: Entry): Date => e.time) as [Date, Date])
Tapauksessasi oletan, että jotain tämän tapaista pitäisi toimia:
const xScale = d3.scaleTime()
.domain(d3.extent<Iterable<Window>, Iterable<Date>>(data, xAccessor) as [Date, Date])
.range([0, dimensions.boundedWidth])
