代码之家  ›  专栏  ›  技术社区  ›  Peter Hudec

TypeScript中泛型类型的子类型推断

  •  3
  • Peter Hudec  · 技术社区  · 7 年前

    我想要一个函数,它接受某个对象并返回其 x 属性需要将对象限制为泛型类型 Type<X> 我希望返回值的类型是属性的类型 x .

    将输入限制为 类型(<);X> 我需要使用 T extends Type<X> 但我必须实际设置 X 对于某些类型值,如 T extends Type<string> 这不适用于 Type<number> T extends Type<any> 它将丢弃 属性

    <T extends Type<any>>(o: T) => T.X <T extends Type<???>>(o: T) => typeof o .

    TypeScript中有什么方法可以做到这一点吗?如果是,如何?

    // Suppose I have this generic interface
    interface Type<X> {
      readonly x: X
    }
    
    // I create one version for foo...
    const foo: Type<string> = {
      x: 'abc',
    }
    
    // ...and another one for bar
    const bar: Type<number> = {
      x: 123,
    }
    
    // I want this function to restrict the type of `o` to `Type`
    // and infer the type of `o.x` depending on the inferred type of `o`,
    // but to restrict to `Type` I must hardcode its X to `any`, which
    // makes `typeof o.x` to evaluate to `any` and the type of `o.x` is lost.
    function getX<T extends Type<any>> (o: T): typeof o.x {
      return o.x
    }
    
    // These are correctly typed
    const okFooX: string = getX(foo)
    const okBarX: number = getX(bar)
    
    // These should result in error but it is OK due to `Type<any>`
    const errorFooX: boolean = getX(foo)
    const errorBarX: boolean = getX(bar)
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Nitzan Tomer    7 年前

    如果我理解正确,那么:

    function getX<T>(o: Type<T>): T {
        return o.x;
    }
    

    然后:

    const errorFooX: boolean = getX(foo); // error: Type 'string' is not assignable to type 'boolean'
    const errorBarX: boolean = getX(bar); // error: Type 'number' is not assignable to type 'boolean'
    

    ( code in playground