generikler - TypeScript'te ilişkili türler
Swift'te ilişkilendirilmiş türler gibi bir kavram vardır.
protocol Container {
associatedtype ItemType // Here it is.
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
struct IntStack: Container {
typealias ItemType = Int // Here again.
mutating func append(item: Int) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Int {
return items[i]
}
var items = [Int]()
mutating func push(item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
}
Bu bir tür genel arayüzlerdir, ancak ilişkilendirilmiş türlerin önemli bir özelliği, bulundukları türün dışından referans verilebilmeleridir.
var x: IntStack.ItemType = someIntStack.pop()
TypeScript'te bunun gibi bir şey yapmak mümkün mü?
Cevap #1
Şu anda Typescript'te ilişkili tipler için böyle bir özellik yok.
İlişkili Türlere Alternatifler
Typescript'te bunun gibi bir şey olmasa da?...
// WILL NOT COMPILE
interface Add<T> {
type Output;
add(other: T): Output;
}
İlişkili tiplerin ele aldığı bazı sorunları farklı derecelerde çözebilecek alternatifler vardır.
Geneli çıkarsamak
Bir generiğe geçirilen türü şu şekilde çıkarabilirsiniz
type ArrayItem<T> = T extends Array<infer I> ? I : never;
Ve bu türü bu şekilde kullanabilirsiniz.
const number: ArrayItem<Array<number>> = 1;
Burada Typescript Playground'da onunla oynayabilirsiniz.
Bir alanın alanını indeksleme
Diyelim ki bunlar gibi bazı türlerin vardı:
type StorageStage<T> =
| { kind: 'initial' }
| { kind: 'loading', promise: Promise<Array<T>> }
| { kind: 'loaded', storage: Array<T> };
class AsyncStorage<T> {
state: StorageStage<T> = { kind: 'initial' };
}
Bu alanlar genel (public) ise, türlerini almak için indeks sözdizimini kullanabilirsiniz.
const storageStage: AsyncStorage<number>["state"] =
{ kind: 'loaded', storage: [1] };
Yine, bunu burada Typescript Playground'da kontrol ediyorsunuz.
