Typescript类的通用类型可以省略

时间:2018-12-01 11:03:05

标签: typescript class generics

使用Typescript和默认的编译器选项对允许或禁止的使用非常严格-例如空值,类属性不在构造函数中初始化。但是当涉及泛型时,可以为一个类定义一个泛型类型,然后在不指定类型的情况下创建一个新类!

class Foo<T> {
    bar(item: T): void {
        console.log('typeof T: ', typeof item)
    }
}

const foo1 = new Foo<string>() // T specified
foo1.bar('hello')
foo1.bar(6) // error TS2345: Argument of type '6' is not assignable to parameter of type 'string'

const foo2 = new Foo() // T missing
foo2.bar('hello')
foo2.bar(6) // works with no complaint

是否可能认为new Foo()是错误的陈述?

如上所述,我正在使用默认的编译器选项,该选项不允许添加永远不会初始化的额外属性a: T

3 个答案:

答案 0 :(得分:4)

您不能在构造函数上遗漏image: {{ printf "%s/%s:%s" .Values.image.repository (.Values.image.image | default "myimage") .Values.image.tag | quote}} 是一个错误(当然可以,但是您需要一些条件类型魔术和一个至少带有一个参数的构造函数)

如果不使用类型参数的默认值提供参数,则可以使该类不可用。默认值为T将解决问题。

never

您还可以在构造函数参数中使用构造函数重载和元组,以使构造函数在省略类型参数(即,类型参数为class Foo<T = never> { bar(item: T): void { console.log('typeof T: ', typeof item) } } const foo1 = new Foo<string>() // T specified foo1.bar('hello') foo1.bar(6) // error TS2345: Argument of type '6' is not assignable to parameter of type 'string' const foo2 = new Foo() // T missing foo2.bar('hello') // err foo2.bar(6) // err )时出现错误

never

答案 1 :(得分:2)

除了其他答案,我想指出的是,TSLint有专门针对这种情况的规则:no-inferred-empty-object-type

启用此规则将使TSLint抱怨TypeScript何时将{}推断为泛型(类似于noImplicitAny编译器标志,仅适用于泛型)。

这似乎正是您想要的。

答案 2 :(得分:1)

  

可以为一个类定义一个通用类型,然后在不指定类型的情况下创建一个新类!

Of course, it's called type argument inference

  

也就是说,我们希望编译器根据传入的参数类型为我们自动设置T的值:

如此

  

是否可以将新的Foo()视为错误的陈述?

否,因为编译器可能根据已经编写的代码将T设置为anystring | number。因此T完全有效。

查看您的代码:

const foo2 = new Foo() // T missing
foo2.bar('hello')
foo2.bar(6) // works with no complaint

为什么会抱怨,编译器必须推断一个类型,因此它正在查看所有用法来推断一个有效的类型。毕竟,之前的代码与以下代码有什么区别:

const foo3 = new Foo() // T missing
foo3.bar(6) 
foo3.bar('hello') // works with no complaint

仅操作顺序。为什么编译器应该假定仅方法的首次使用才能确定T的类型?如果是以下情况怎么办:

const foo3 = new Foo() // T missing
if (someValueOrBooleanReturningFunction) {
  foo3.bar(6) 
}
foo3.bar('hello') // works with no complaint

那又是什么?也许可以或者不能确定if的值,但是由于未指定a类型,因此无论哪种方式,编译器都必须确定T是什么。