reactjs - TypeScript: paketler için tip tanımlarını geçersiz kılma ve düzeltme
Grafikler için React victory kütüphanesini kullanıyorum ve TypeScript kullanıyorum. Projeme @types/victory paketini ekledim, ancak maalesef ihtiyacım olan birçok key tanımı eksik. Bazı arayüzlerde birkaç özellik eksikti, bu yüzden (bu cevabı kullanarak) bu özellikleri arayüzlere eklemek için özel bir dosya oluşturdum.
Ama şimdi bir problemim var: Olaylar için tanımlanmış arayüzde eventHandlers adlı bir özellik tanımlanmış, ama yine önemli bir tanımı eksik, nasıl tanımlandığı:
export interface EventPropTypeInterface<TTarget, TEventKey> {
/* other properties */,
eventHandlers: {
[key: string]:
{ (event: React.SyntheticEvent<any>): EventCallbackInterface<TTarget, TEventKey> } |
{ (event: React.SyntheticEvent<any>): EventCallbackInterface<TTarget, TEventKey>[] }
}
Ama sorun şu ki, fonksiyon ikinci bir parametre kabul etmeye izin vermeli, örnek (ikinci argümanın türünden emin değilim, bu yüzden any kullandım):
{ (event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey> }
Yani, bu özelliği kendi tanımımın içine eklemeyi denedim:
declare module "victory" {
export interface EventPropTypeInterface<TTarget, TEventKey> {
eventHandlers: {
[key: string]:
{ (event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey> } |
{ (event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey>[] }
}
}
Ama şimdi TypeScript, @typings dizinindeki index.d.ts hakkında şikayet ediyor ve eventHandlers'ın tanımladığım türde olması gerektiğini söylüyor.
Sağlanan tür tanım dosyasını kullanmanın ve diğer ara yüzlerde sadece yeni özellikler eklediğimde yaptığım gibi kendi tanımım ile bir şekilde "artırmanın" bir yolu var mı?
Cevap #1
Bu işe yarayabilir. Sorun, türlerin genişletilebilirlik düşünülerek tanımlanmamış olmasıdır.
Nesne literal türleri, örneğin {x: string} birçok durumda harikadır, ancak karmaşık iç içe yapılarda değildir.
Sebep, bu türlerin, tür takma adlarına benzer şekilde, genişletilebilirliği sağlamak için gerekli olan bildirim birleştirmesine tabi olmamalarıdır.
eventHandlers nesnesinin olası değerlerinin türleri bir interface olarak beyan edilmiş olsaydı, ek yükleme yöntemleri ekleyerek kolayca genişletilebilir olurdu.
Aşağıdaki, kendi içinde bağımsız örnek, tipler eventHandlers değer tipi için bir interface bildirimi kullanacak şekilde yeniden düzenlendiğinde genişletilebilirliğin ne kadar kolay olduğunu göstermektedir:
declare module "victory" {
interface EventHandler<TTarget, TEventKey> {
(event: React.SyntheticEvent<any>): EventCallbackInterface<TTarget, TEventKey>
(event: React.SyntheticEvent<any>): EventCallbackInterface<TTarget, TEventKey>[]
}
export interface EventPropTypeInterface<TTarget, TEventKey> {
eventHandlers: {
[key: string]: EventHandler<TTarget, TEventKey>
}
}
}
declare module "victory" {
// this interface merges with the original, declaring additional overloads of the all signature
interface EventHandler<TTarget, TEventKey> {
// declare overloads
(event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey>
(event: React.SyntheticEvent<any>, dataPoint: any): EventCallbackInterface<TTarget, TEventKey>[]
}
}
type EventCallbackInterface<T, U> = {}
declare namespace React {
export type SyntheticEvent<T> = {};
}
Test :
import victory = require("victory");
declare const handlerProps: victory.EventHandler<{}, {}>;
handlerProps({}, { x: 1, y: 2 }); // works fine
İşte bunun çalışırken bir bağlantısı
Böyle bir genişletilebilirliği sağlamak için npm:@types/victory öğesini bu şekilde bir interface kullanacak şekilde değiştiren bir Pull Request'i https://github.com/DefinitelyTyped/DefinitelyTyped adresine göndermenizi şiddetle tavsiye ederim.
