我在使用PureScript进行函数式编程blog post之后。在JavaScript中有一个Box的示例:
const Box = x => ({
map: f => Box(f(x)),
fold: f => f(x),
inspect: () => `Box(${x})`
});
我想使用TypeScript对其进行输入,以便像这样对代码进行语法检查:
const nextCharForNumberString = str =>
Box(str)
.map(s => s.trim())
.map(s => new Number(s))
.map(i => i + 1)
.map(i => String.fromCharCode(i))
.fold(c => c.toLowerCase());
我试图像这样输入Box:
interface IBox<T> {
map: <U>(T) => IBox<U>;
fold: <U>(T) => U;
inspect: (T) => string;
}
const Box: <T>(x: T) => IBox<T> = x => ({
map: f => Box(f(x)),
fold: f => f(x),
inspect: () => `Box(${x})`
});
让我知道如何正确输入Box功能。为了简化语法,我也试过了:
function Box<T>(x: T): IBox<T> {
return {
map: <U>(f): IBox<U> => Box(f(x)),
fold: <U>(f): U => f(x),
inspect: () => `Box(${x})`
};
}
我的尝试都没有。我希望在编译时捕获它:
const s: IBox<String> = Box(5)
.map(x => x * x)
.map(x => x.toString())
.map(x => x * x)
.fold(x => x);
在我看来,使用TypeScript可以实现这一点。任何见解将不胜感激!
答案 0 :(得分:2)
当然,我认为你非常接近。这是一种键入Box<T>
界面的方法:
interface Box<T> {
map<U>(f: (t: T) => U): Box<U>;
fold<U>(f: (t: T) => U): U;
inspect(): string;
}
这是一种键入Box
函数的方法,它接受T
类型的参数并生成Box<T>
(您可以使用Box
作为类型名称和函数名称,因为值名称和类型名称存在于不同的名称空间中):
const Box = <T>(x: T): Box<T> => ({
map: f => Box(f(x)),
fold: f => f(x),
inspect: () => `Box(${x})`
}); // compiles fine
然后您将在编译时捕获问题,如下所示:
const badS = Box(5)
.map(x => x * x)
.map(x => x.toString())
.map(x => x * x) // error, x is a string, you cant multiply it
.fold(x => x);
能够修复它:
const goodS = Box(5)
.map(x => x * x)
.map(x => x.toString())
.fold(x => x); // goodS is type string
console.log(goodS); "25"
希望有所帮助;祝你好运!