简体   繁体   English

打字稿通用类型保护

[英]typescript generic type guard

I have variable that can be either of type C1[] or C2<C1>[] how do I create a type guard for the variable?我的变量可以是C1[]C2<C1>[]类型,如何为变量创建类型保护?

interface C<T>{
   key: string;
   secret: T;
}

private isC(d: Foo[] | C<Foo>): d is C<Foo>[] {
    return (<C<Foo>>)d[0].key !== undefined
}

The method isC is not compiling.方法isC未编译。

There are multiple issues, here: 这里有多个问题:

  1. The isC function needs Foo as a type parameter. isC函数需要Foo作为类型参数。 This means it needs to be declared like this: 这意味着需要这样声明:

     private isC<Foo>(... 
  2. The return type definition of isC does not match its input parameters. isC的返回类型定义与它的输入参数不匹配。 The return type declares that isC returns true , when its parameter d is of Type C<Foo>[] , but the input type is restricted to Foo[] or C<Foo> (neither of them being C<Foo>[] ). 当其参数d的类型为C<Foo>[] ,返回类型声明isC返回true ,但是输入类型限于Foo[]C<Foo> (它们都不是C<Foo>[] )。 。

    This declaration should work: 该声明应该起作用:

     private isC<Foo>(d: Foo[] | C<Foo>[]): d is C<Foo>[] { ... 
  3. (<C<Foo>>)d[0] is not a valid type cast. (<C<Foo>>)d[0]不是有效的类型转换。 Try this, instead: 试试这个,代替:

     return (d as C<Foo>[])[0].key !== undefined 

Also see this playground with compiling example . 另请参阅带有编译示例的操场

I'm facing the same problem and i wrote this little function: 我面临着同样的问题,我写了这个小函数:

function isTypeOf<K>(arg: any): arg is K {
    let result: boolean = false;
    const targetedType = { ...arg } as K;

    Object.keys(arg).forEach((prop: string) => {
        result = some(Object.keys(targetedType), (x: string) => x === prop);
    });

    return result;
 }

It's a bit sad that the only way is to test if a property exist on the 'arg' according to the targeted type ... 唯一的方法就是根据目标类型测试'arg'上是否存在属性,这有点令人遗憾。

*The 'some' function come from lodash *“某些”功能来自lodash

private isC(d: Foo[] | C<Foo>): d is C<Foo>[] {
    return (d as C<Foo>[])[0].key !== undefined
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM