仅当泛型类型为字符串时才使用 Typescript 类方法

问题描述 投票:0回答:2

使用泛型类型类,我希望某些方法可用仅当泛型类型是“字符串”时。

使用以下代码

class MyClass<T = string> {
  value: T = null;

  setDate(m: Moment) {
    // could be used only if T is string
    value = m ? m.format('YYYY-MM-DD') : null;
  }

}

给我错误

Argument of type 'string' is not assignable to parameter of type 'T'

这非常清楚并且完全有意:

Moment.format()
返回
string
。 :D

是否有正确的方法使

setDate()
方法仅在
T
string
时才可用?

提前,非常感谢。


我知道我可以使用

m.format('YYYY-MM-DD') as unknown as T
解决问题,但它看起来像是一种解决方法,而不是真正的打字稿解决方案。

我了解条件类型,但我认为它不能解决我的问题。至少,我没有找到如何弄清楚。

typescript class methods typescript-generics
2个回答
1
投票

make 函数在不正确的泛型上有

never
arg

type Moment = {format(s:string):string};

type SimpleEquals<T, V> = [T] extends [V] ? [V] extends [T] ? true : false : false;


class MyClass<T = string> {
  value: T | null = null;

    // could be used only if T is string
  setDate(m: SimpleEquals<T, string> extends true ? Moment : never) {
    this.value = m ? m.format('YYYY-MM-DD') as T : null;
  }
}

declare let m: Moment; 

new MyClass<string>().setDate(m) // ok

new MyClass<number>().setDate() //err
new MyClass<number>().setDate(m) //err

new MyClass<string | number>().setDate() //err
new MyClass<string | number>().setDate(m) //err

new MyClass<'qwe'>().setDate() //err
new MyClass<'qwe'>().setDate(m) //err


0
投票

为了扩展 Dimava 的解决方案,只要该方法不应该存在,您就可以将

this
的类型设置为
never

class MyClass<T = string> {
  setDate(
    this: T extends string ? MyClass<T> : never,
    m: Moment
  ) {
    ...;
  }
}

此策略的优点是它甚至适用于不带任何参数的方法。

请注意,

this: Type
是用于键入 this 对象的
特殊 TypeScript 语法
。 TypeScript 编译器会删除
this
伪参数,因此 JavaScript 引擎永远看不到它。

© www.soinside.com 2019 - 2024. All rights reserved.