我可以将类型限制为接口的值吗?

时间:2019-06-04 21:00:12

标签: typescript typescript-typings

这就是我想要的:

interface ValidValues {
  TOP: number;
  BOTTOM: number;
}

function f(b: valuesof(ValidValues)) {
}

function g(valid: ValidValues) {
  f(valid.TOP);
  f(3); // should not compile
}

即使3并非相等等于valid.TOP或valid.BOTTOM,也不是不可能,因为无法在编译时进行演示,但我希望它会出错。

可能吗?

是的,我知道没有什么可以阻止用户构建自己的ValidValues实现并将TOP或BOTTOM设置为3。在这种情况下,JavaScript库为我提供了一个函数给了我一个充满了可以调用它的值的对象,而我试图在Typescript中键入它。

2 个答案:

答案 0 :(得分:2)

您似乎希望让branded primitives之类的类型ValidValue可以将分配给 number,但是不能从分配 number。这是一个技巧,您可以将number与包含“ brand”属性的对象类型相交,这样即使在运行时,编译器也可以分辨出普通number和品牌ValidValue之间的区别。没什么区别(ValidValue在运行时不会真正拥有品牌属性)。

类似这样的东西:

type ValidValue = number & { __brand: "ValidValue" };

interface ValidValueObj {
  TOP: ValidValue;
  BOTTOM: ValidValue;
}

让我们看看它是如何工作的:

function f(b: ValidValue) {}

function g(valid: ValidValueObj) {
  f(valid.TOP);
  f(3); // error as desired
}

如果您要强制编译器接受number作为ValidValue,则可以使用type assertions

function getValidValueObj(top: number, bot: number): ValidValueObj {
    return {
        TOP: top as ValidValue,
        BOTTOM: bot as ValidValue
    }; 
}

有帮助吗?祝你好运!

Link to code

答案 1 :(得分:0)

  

可能

不。没有界面:

interface ValidValues {
  TOP: number;
  BOTTOM: number;
}

任何接受ValidValues中的值的东西都将接受任何number(例如3