typescript - Hata: 'number | undefined' türü 'number | { valueOf(): number; }' türüne atanamaz mı?
Elimde bu dizi türü var:
interface Details {
Name: string;
URL: string;
Year: number;
}
interface AppState {
data: Details[];
}
Bir x ekseni oluşturmak için D3 kullanıyorum, bu şekilde:
createChart = () => {
const { data } = this.state;
const width = 900,
height = 600;
// x-axis
const x = d3
.scaleLinear()
.domain([
d3.min(data, ({ Year }) => (Year ? Year - 1 : 0)), // ERROR
d3.max(data, ({ Year }) => (Year ? Year + 1 : 0)) // ERROR
])
.range([0, width]);
};
İşaretli satırlarda d3.min ve d3.max kullanırken aşağıdaki hatayı alıyorum:
Type 'number | undefined', type 'number | { valueOf(): number; }' türüne atanamaz. Type 'undefined', type 'number | { valueOf(): number; }' türüne atanamaz.
Bunu nasıl çalıştırabilirim?
Cevap #1
Sizin d3.min() çağrınız için derleyici aşağıdaki tür tanımını kullanacaktır:
export function min<T, U extends Numeric>(array: Iterable<T>, accessor: (datum: T, index: number, array: Iterable<T>) => U | undefined | null): U | undefined;
Gördüğünüz gibi, fonksiyon ya U döndürebilir—sizin durumunuzda Details.Year türü, yani number—ya da undefined. Ancak bu, sadece sayılardan veya sayılara dönüştürülebilecek değerlerden oluşan bir dizi alan .domain() yönteminin tür tanımıyla eşleşmez:
domain(domain: Array<number | { valueOf(): number }>): this;
Bu, neden hata aldığınızı açıklar. Aynı şekilde, d3.max() için de geçerlidir.
Belgelere bakıldığında, d3.min()'in undefined döndürmesinin nedenleri oldukça sınırlıdır:
Eğer yinelenebilir nesne karşılaştırılabilir değerler içermiyorsa, tanımsız döner.
Verilen kodunuzla bu sorunla karşılaşmayacağınız garanti edilir. Bu nedenle d3.min() ve d3.max() dönüş değerlerini güvenle number olarak dönüştürebilirsiniz:
const x = d3
.scaleLinear()
.domain([
d3.min(data, ({ Year }) => (Year ? Year - 1 : 0)) as number, // cast to number
d3.max(data, ({ Year }) => (Year ? Year + 1 : 0)) as number // cast to number
])
.range([0, width]);
