LoginSignup
11

More than 5 years have passed since last update.

Swiftに慣れた人がTypeScriptをうまく書くコツ

Posted at

Swiftに慣れるとどうしても Generics でclassの定義をしたくなりませんか?
Firebase Cloud Functionsを初めてからとことんTypeScriptを書くことが多くなってきたのでちょっとしたTipsを紹介します。

この文章はあくまでもSwiftに慣れた人がTypeScriptを書く場合のコツです。TypeScript本家の方でもっといい方法を知っている方がいればぜひご教示下さい。

ProtocolとInterface

SwiftのProtocolに相当するTypeScriptの構文はInterfaceです。
TypescriptのInterfaceはSwiftのProtocol Extensionができないなど物足りなさも感じますが、Classに必要なプロパティやファンクションを定義する意味では充分に機能します。

protocol AProtocol {

}
interface AProtocol {

}

ここまでは非常に似ているが。。

Genericsをつけると途端にわかりにくい

さぁこれにGenericsを加えていきましょう。

Swift

protocol AProtocol {
    init()
}

protocol BProtocol {
    associatedtype A: AProtocol
}

class Fuga: AProtocol {
    required init() {}
}

class Hoge<T: AProtocol>: BProtocol {
    typealias A = T
    func fuga() -> A {
        let a: A = A()
        return a
    }
}

let hoge: Hoge<Fuga> = Hoge()
let a: Fuga = hoge.fuga()

TypeScript

interface AProtocol {

}

interface BProtocol<A extends AProtocol> {

}

class Fuga implements AProtocol {

}

class Hoge <A extends AProtocol> implements BProtocol<A> {

    private _A: { new(): A }

    fuga(): A {
        const a: A = new this._A()
        return a
    }
}

const hoge: Hoge<Fuga> = new Hoge()
const a: Fuga = hoge.fuga()

考え方を整理するポイントは2つ

  • associatedtype
  • { new(): A }

TypeScriptでassociatedtypeっぽいことをする

Swiftのassociatedtypeは、TypeScriptでは BProtocol<A extends AProtocol>のように依存するプロトコルを宣言します。

Genericsの型を初期化

TypeScriptでGenericsの型を初期化するには{ new(): A }が必要です。Swiftのassociatedtypeの代わりに

private _A: { new(): A }

を宣言しています。こうすることでclass内ではどこでもAを初期化することが可能になります。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11