2016-04-27 63 views
15

比方說,我有一個接口A如何在手稿中表達這一點?

interface A { 
    foo: number 
    bar: string 
} 

而且我有一個泛型類型Option

type Option<T> = { 
    map:() => T 
} 

然後我從AOption創建一個新的接口B

interface B { 
    foo: Option<number> 
    bar: Option<string> 
} 

如何讓這個操作更一般? IE瀏覽器。我想這個API是:

type B = Lift<A> 

LiftOptionA每個成員自動映射。請注意,A可以有任意數量的任何類型的成員。

我該如何實現Lift?如果這在TypeScript中不可行,是否有人有Scala/Haskell解決方案?

回答

2

好消息:With TypeScrip牛逼2.1.0,這是現在可以通過Mapped Types

type Option<T> = { map() => T }; 
type OptionsHash<T> = { [K in keyof T]: Option<T[K]> }; 
function optionsFor<T>(structure: T): OptionsHash<T> { ... }; 

let input = { foo: 5, bar: 'X' }; 
let output = optionsFor(input); 
// output is now typed as { foo: { map:() => number }, bar: { map:() => string } } 

相反還可能:

function retreiveOptions<T>(hash: OptionsHash<T>): T { ... }; 

let optionsHash = { 
    foo: { map() { return 5; } }, 
    bar: { map() { return 'x'; } } 
}; 
let optionsObject = retreiveOptions(optionsHash); 
// optionsObject is now typed as { foo: number, bar: string } 
+1

映射類型超級酷 - 感謝您的答案。 – bcherny

4

我還沒有看過TypeScript一段時間(我認爲它是1.0版本),所以我不能確定它現在是否存在。

你想要什麼需要類型系統功能稱爲更高kinded類型;它允許通過將它們作爲參數傳遞給類型構造函數來構造類型,非常像函數應用程序,被提升到類型級別。

您必須調整A的定義才能完成此工作。以下是我想達到你在Haskell想要的東西:

-- First, I need a more general definition for A 
data GeneralizedA f = A { foo :: f Int, bar :: f String } 

-- So that I can re-encode the original A like this : 
type A = GeneralizedA Identity 

-- Guessing what the Option type would be since 
-- Haskell's type system is more precise here : 
data Option a = Option { optionMap :: IO a } 

-- And here's the result : 
type B = GeneralizedA Option 
9

您正在尋找higher-kinded types。這是Scala:

trait FooBar[M[_]] { 
    val foo: M[Integer] 
    val bar: M[String] 
} 

type Identity[X] = X 
type A = FooBar[Identity] 
type B = FooBar[Option] 

你可以使用任何二階類型,例如:

type C = FooBar[List] 

但這些不會編譯:

// type S = FooBar[String] ---> String is a first-order type 
// type M = FooBar[Map] ---> Map[K, V] is a third-order type 

不幸的是,尚未作出它到TypeScript中,但有一個公開的問題:https://github.com/Microsoft/TypeScript/issues/1213

+0

無賴 - upvoted的問題。 – bcherny