调用函数作为参数类型

时间:2019-09-07 01:01:39

标签: typescript

假设我有一个功能

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'函数返回的字符串,有可能吗?

1 个答案:

答案 0 :(得分:6)

这看起来像branded primitives的用例,这是一种在编译时假装您有一种特殊类型的string与其他string值不同的方法。 。但当然在运行时只有string

type FooStr = string & { __fooStr: true };

这里FooStr既是string,又是假定具有__fooStr属性的对象。我们必须使用type assertionstring转换为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

好的,希望能有所帮助;祝你好运!

Link to code


更新:您可以通过使其具有私有属性来阻止其他人制作FooStr实例,如:

declare class PrivateFooStr {
  private __fooStr: true;
  private constructor();
}
type FooStr = string & PrivateFooStr;

但是由于很容易获得带有类型断言的FooStr,所以我不确定这样做是否值得。您可能只需要一些说明文件FooStr仅是从foo()返回的字符串,并且用户不应尝试违反该文件。