TypeScript neden genel mirasta eksik özellik hakkında şikayet ediyor?
Aşağıdaki test durumunu göz önünde bulundurun :
interface BaseFoo {}
interface FooAdapter {
method<F extends BaseFoo>(foo:F):string;
}
interface ConcreteFoo extends BaseFoo {
value:string;
}
class ConcreteFooAdapter implements FooAdapter {
method(foo: ConcreteFoo): string {
return foo.value;
}
}
Tek hata, TypeScript'in şikayet ettiği method imzasıyla ilgilidir:
Tür 'BaseFoo' içinde 'value' özelliği eksik, ancak tür 'ConcreteFoo' içinde gerekli.
F genelinin onu genişletmesi gerektiği halde value neden BaseFoo içinde bulunuyor?
Ama daha da önemlisi, bu hatanın olmaması için bunu nasıl düzeltirsiniz?
Düzenle
İşte araştırmaya çalıştığım başka bir alternatif çözüm, ancak benzer bir başarısızlıkla:
interface BarAdapter {
method<F>(bar:F):string;
}
type Bar = {
value:string;
}
class ConcreteBarAdapter implements BarAdapter {
method(bar:Bar):string {
return bar.value;
}
}
Bu, F'nin Bar türüne atanabilir olmadığını bildiriyor ve nedenini anlamıyorum.
Cevap #1
Eğer tek kriteriniz parametrenin BaseFoo'yu genişletmesi ve dönüş değerinin bir string olmasıysa, generics'e hiç ihtiyacınız olmayabilir, bu yeterli olacaktır:
interface BaseFoo { }
interface FooAdapter {
method(foo: BaseFoo): string;
}
interface ConcreteFoo extends BaseFoo {
value: string;
}
class ConcreteFooAdapter implements FooAdapter {
method(foo: ConcreteFoo): string {
return foo.value;
}
}
Bu, generics ile yaptığınız denemede olduğu kadar güçlü bir tip güvenliği sağlar. TypeScript, uygulayıcıda method'u extend method(foo: BaseFoo): string olarak kısıtlar.
Ancak, eğer adaptörleri belirli bir method imzasının uygulanabilirleri olarak kullanmanız gerekiyorsa, o zaman interface'e genel parametre eklemeniz ve sonra onu uygularken tipi açıkça belirtmeniz gerekir:
interface BaseFoo { }
interface FooAdapter<F extends BaseFoo> {
method(foo: F): string;
}
interface ConcreteFoo extends BaseFoo {
value: string;
}
class ConcreteFooAdapter implements FooAdapter<ConcreteFoo> {
method(foo: ConcreteFoo): string {
return foo.value;
}
}
