假设我有一个功能
const foo = (str: string) => str + "foo"
我想拥有另一个函数,仅接受带有适当参数的该函数的调用。 一些伪代码,如果不清楚我想要什么:
const bar = (fooStr: foo(string)) => fooStr + "bar"
bar(foo("typical string")) //okay
bar("jfifem") //error
bar("typical stringfoo") //error
ReturnType给我字符串,但是我不想要任何字符串,我只需要'foo'函数返回的字符串,有可能吗?
答案 0 :(得分:6)
这看起来像branded primitives的用例,这是一种在编译时假装您有一种特殊类型的string
与其他string
值不同的方法。 。但当然在运行时只有string
:
type FooStr = string & { __fooStr: true };
这里FooStr
既是string
,又是假定具有__fooStr
属性的对象。我们必须使用type assertion将string
转换为FooStr
,因为从根本上讲,这是一个有用的谎言,我们告诉编译器:
const foo = (str: string) => (str + "foo") as FooStr;
现在foo()
取一个string
并返回一个FooStr
。因此,我们可以使bar()
取一个FooStr
并返回一个string
:
const bar = (fooStr: FooStr) => fooStr + "bar";
这为您提供了您想要的行为:
bar(foo("typical string")); //okay
bar("jfifem"); //error
bar("typical stringfoo"); //error
好的,希望能有所帮助;祝你好运!
更新:您可以通过使其具有私有属性来阻止其他人制作FooStr
实例,如:
declare class PrivateFooStr {
private __fooStr: true;
private constructor();
}
type FooStr = string & PrivateFooStr;
但是由于很容易获得带有类型断言的FooStr
,所以我不确定这样做是否值得。您可能只需要一些说明文件FooStr
仅是从foo()
返回的字符串,并且用户不应尝试违反该文件。