English 中文(简体)
类型:保护普通类的类型?
原标题:TypeScript - type guarding a class generic?
  • 时间:2023-12-29 12:04:34
  •  标签:
  • typescript

How to make work in TS a generic class that can return different types based on its generic parameter (set in the constructor)?

type Type =  foo  |  bar ;

interface Res {
     foo : {foo: number};
     bar : {bar: string};
}

class MyClass<T extends Type> {
    constructor(readonly type: T) {}

    public run(): Res[T] {
        if (is(this,  foo )) {
            return { foo: 123 };
        }
        return { bar:  xyz  };
    }
}

function is<T extends Type>(instance: MyClass<Type>, type: T): instance is MyClass<T> {
    return instance.type === type;
}

可在

Type { foo: number; } is not assignable to type Res[T] . Type { foo: number; } is not assignable to type { foo: number; } & { bar: string; } . Property bar is missing in type { foo: number; } but required in type { bar: string; } .

但常识(和类型警卫)指出,通用的<代码>T显然是正确的类型......因此不能适用于返回线?

问题回答

Ah, I don t think it is possible to restrict the return type of a function from within the function. I believe the best you can do is to remove the error with a typecast:

public run(): Res[T] {
    if (is(this,  foo )) {
        return { foo: 123 } as Res[T];
    }
    return { bar:  xyz  } as Res[T];
}

初步答复:

我怀疑,打字体没有知道如何缩小对<代码>is(该, foo)的号召,因为您对“代码”的功能定义是。 标识:

function is<T extends Type>(instance: MyClass<Type>, type: Type): instance is MyClass<T>

或许应当:

function is<T extends Type>(instance: MyClass<Type>, type: T): instance is MyClass<T>

因此,汇编者可根据第二点的类型加以缩小。 或者,你在称之为“准则”时可以具体指出一般性论点:is< foo >this, foo >

http://www.typescriptlang.org/docs/handbook/2/generics.html 不能真正在文字上很好地合作。 当你检查<条码>is(这里, foo 时,可缩小thisthis &MyClass<“foo”>,但对于普通参数代码//code>。 您可能会期望或希望T>将改为_constraining from Type to only >foo”,但不是。 这意味着<代码>{foo:123}<>>>>>> /code>不能被指定到<代码>Res[T]上,而且你有错误。

请注意,虽然<代码>this.type ===“foo” 系指T_>foo>,但一般而言,这样做实际上是不正确的。 ∗∗∗∗ 详情请union category>> ́>,并确定this.type=“foo” 消除这种可能性。 最好可以说,你知道<代码>T必须与“foo”>有些重叠,因此。 T & “foo” is not never, 但这是强制执行或明示的十分trick缩的制约因素。

有几个公开的专题要求通过控制流动分析对通用参数进行某种重新调整。 The most relevant those for this Code example here are microsoft/Type #27808 仅限>>>>>t-m>>>-foobar",且不得加入该联盟;microsoft/Type#33014。 这将使汇编者看到哪怕是<代码>。 T是正式结合,可以安全返回<代码>{foo:123}。 两者都有可能使你的法典成为现实,但现在它们不属于语言的一部分,需要围绕它开展工作。


最为容易的工作只是使用字词,以告诉汇编者不要担心核实这些类型。 例如:

public run(): Res[T] {
    if (is(this,  foo )) {
        return { foo: 123 } as Res[T]; // okay
    }
    return { bar:  xyz  } as Res[T]; // okay
}

这是你朝着对你的法典作起码改动的方向迈进的最快捷途径。 但是,我只想知道,你会重新承担起从这里的汇编者进行分类检查的责任。 您可以将上述检查改为(!is(this, foo ),汇编者仍然乐于这样做。 因此,在提出你正在讲述真相的那种说法时,你必须小心。


如果在这方面从汇编者那里获得某种类型的安全保障更为重要,那么,工作范围将涉及从类型保护和控制流动分析中重新定位,并转向通用的索引<>。 页: 1 具有下列关键特性的 和回归:

public run(): Res[T] {
    return {
        foo: { foo: 123 },
        bar: { bar:  xyz  }
    }[this.type]; // okay
} 

这可能看杂货,但与核对<代码>this.打字/代码”的逻辑相似,然后根据结果指导控制流动。 这里唯一的重大区别是,尽管它放弃了其中一项,但实际计算出两种可能的回报值:{foo:123}-bar:xyz } 每次都使用>>>>>>>>>,尽管它放弃了其中一项。 对小物体而言,这种字面没有副作用,可能就没有问题了。 但是,如果你真的想像以前那样做,那么你可以使用getters,以确保只有与实际this.打上相应的代码。 执行价值:

public run(): Res[T] {
    return {
        get foo() { return { foo: 123 } },
        get bar() { return { bar:  xyz  } }
    }[this.type]; // okay
}

如今,this.type is "foo>,return{foo: 123}将运行,但return{bar:xyz }将不适用。

您可以修改这一执行,以做其他事情,但基本做法是,你通过实际指数化操作,而不是通过<条码>,<><>>>>>>>>><>代>。


因此,你走了。 普通警卫和打字员不准备使用这些语言,你可以通过放松检查类型,或使用非专利警卫。

马达加斯加 4. 与代码的游乐联系





相关问题
store data in memory with nestjs

I am trying to persist some data in my nestjs server so I can then use that data in my client app through http requests. I have created a products.service.ts file with the function getAllData() that ...

React Hook Form Error on custom Input component

I am having a problem when I use react hook form + zod in my application, in short the inputs never change value and I get the following error in the console: Warning: Function components cannot be ...

Updatable promises using proxy in JavaScript

EDIT: I ve updated this question, and the old question is moved here. A POC can be found on this jsfiddle or the snippet below GOAL: The goal here is to make or rather simulate a promise that can be ...