【问题标题】:Typescript generic class in object对象中的打字稿泛型类
【发布时间】:2020-10-11 07:35:29
【问题描述】:

我想做一个通用的打字稿类。但是当类在对象内部时它不起作用。我已经尝试了很多代码,但它们对我不起作用:(

我已经尝试了所有这些。

// this is my class object
const obj1 = {
    Foo: class<T> {
        foo: T

        constructor({ foo }: { foo: T }) {
            this.foo = foo;
        }

        getFoo(): T {
            return this.foo
        }

        setFoo(t: T): T {
            this.foo = t
            return this.foo
        }
    }
}


// This works: it is typechecked
let a = new obj1.Foo({ foo: 0 })
a.getFoo()      // number
a.setFoo('123') // error


// None of this works
// uncomment them to see errors

// let b: obj1.Foo                                      = new obj1.Foo({ foo: 0 })
// let b: obj1.Foo<number>                              = new obj1.Foo({ foo: 0 })
// let b: typeof obj1.Foo                               = new obj1.Foo({ foo: 0 })
// let b: typeof obj1.Foo<number>                       = new obj1.Foo({ foo: 0 })
// let b: typeof obj1.Foo.prototype                     = new obj1.Foo({ foo: 0 })
// let b: typeof obj1.Foo.prototype<number>             = new obj1.Foo({ foo: 0 })
// let b: typeof obj1["Foo"]["prototype"]               = new obj1.Foo({ foo: 0 })
// let b: typeof obj1["Foo"]["prototype"]<number>       = new obj1.Foo({ foo: 0 })


b.getFoo()      // any
b.setFoo('123') // works (it should error instead)

typescript playground link

谢谢,但抱歉英语不好

【问题讨论】:

  • 嗨。对于什么目的,您在对象中包含类声明?如果你想实现命名空间逻辑,那么应该通过typescriptlang.org/docs/handbook/…来实现。
  • 我想使用命名空间结构,但将所有命名空间保存在一个输出文件中
  • 不幸的是我自己无法更改它@НиколайГольцев

标签: typescript generics


【解决方案1】:

这就是你可以做你想做的事:

namespace customNamespace {
    export class Foo<T> {
        private foo: T;

        constructor({ foo }: { foo: T }) {
            this.foo = foo;
        }

        getFoo(): T {
            return this.foo;
        }

        setFoo(t: T): T {
            this.foo = t;
            return this.foo;
        }
    }
}

// This works: it is typechecked
let a = new customNamespace.Foo({ foo: 0 });
a.getFoo();      // number
a.setFoo('123'); // error


// None of the following are typechecked
// uncomment them to see errors

// let b: obj1.Foo                                      = new obj1.Foo({ foo: 0 })
let b: customNamespace.Foo<number>                              = new customNamespace.Foo({ foo: 0 });
// let b: typeof obj1.Foo                               = new obj1.Foo({ foo: 0 })
// let b: typeof obj1.Foo<number>                       = new obj1.Foo({ foo: 0 })
// let b: typeof obj1.Foo.prototype                     = new obj1.Foo({ foo: 0 })
// let b: typeof obj1.Foo.prototype<number>             = new obj1.Foo({ foo: 0 })
// let b: typeof obj1["Foo"]["prototype"]               = new obj1.Foo({ foo: 0 })
// let b: typeof obj1["Foo"]["prototype"]<number>       = new obj1.Foo({ foo: 0 })


b.getFoo()      // old: any, now: typechecked!
b.setFoo('123') // old: works (it should error instead), now: got an error!

【讨论】:

  • 不使用namespace 有什么办法吗?如果可能的话,我真的想保留我当前的结构(一个普通对象)。无论如何,感谢您的替代方案。
  • 我认为不,你不能那样做。因为您试图将 obj1.Foo 用作类型,但从 Typescript 的角度来看,它是一个值,并且在声明另一个变量类型时无法用它来表示泛型类型。因此,您最多可以使用 typeof obj1.Foo.prototype 作为泛型类型可以是任何类型的类型,这是没有意义的。
猜你喜欢
  • 2019-01-16
  • 1970-01-01
  • 2020-05-25
  • 2017-09-15
  • 2021-12-06
  • 2021-11-26
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多