断言类型必须与接口匹配,但保留原始类型

时间:2018-07-22 05:43:40

标签: typescript

我想表达一个变量匹配一个类型,但保留它的确切类型;即该变量的确切类型扩展了接口,但它是它自己的类型。例如:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

   ....

   override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      let index = myTable.indexPathForSelectedRow
      let indexNumber = index?.row
      let secondVC = segue.destination as! DetailVCViewController 
      secondVC.myDescription = hotel.description[indexNumber!]
      secondVC.array = hotel.array[indexNumber!]

   }
}

我可以通过删除interface TypedLeaves<T> { [k: string]: TypedLeaves<T> | T; [k: number]: TypedLeaves<T> | T; } const x: TypedLeaves<number> = { foo: { bar: 5 }, baz: 8 }; // the following line will complain that x.foo might be a number; // but I already know it's not! // I want `x` to be checked against `TypedLeaves<number>`, but not // lose the specificity of its type without the annotation. const y = x.foo.bar + x.baz; 上的类型,然后创建一个实际上无关紧要的虚拟变量来做到这一点,就像这样:

x

但是我不想仅仅为了执行此检查而创建无效代码。

谢谢!

1 个答案:

答案 0 :(得分:1)

没有一种干净的方法可以执行此操作,on选项是创建执行检查的通用函数。

interface TypedLeaves<T> {
    [k: string]: TypedLeaves<T> | T;
    [k: number]: TypedLeaves<T> | T;
}

function createTypedLeaves<TLeaf>() {
    return function <T extends TypedLeaves<any>>(o: T) {
        return o
    }
}
const x = createTypedLeaves<number>()({ foo: { bar: "5" }, baz: 8 });
const y = x.foo.bar + x.baz;

无用函数旁边的缺点是,由于我们需要为叶子类型指定一个显式参数(因为否则打字稿只会创建一个并不会给出错误的联合)。因为我们要指定TLeaf,但希望编译器推断T,所以我们需要一个函数,该函数应返回一个函数以至少使其起作用,直到在3.1中获得Named type arguments & partial type argument inference为止。或为每种类型创建专用功能(又称硬编码TLeaf = number

要执行检查的变量旁边的另一个选项是使用类型来帮助进行检查,因为删除了类型,该类型不会在运行时创建代码:

type CheckTypedLeaves<TLeaf, TTypedLeaves extends TypedLeaves<TLeaf>> = TTypedLeaves;
const x = { foo: { bar: 5 }, baz: 8 };
type xCheck = CheckTypedLeaves<number, typeof x>