是否可以标记特定方法模式以返回特定类型?

Posted

技术标签:

【中文标题】是否可以标记特定方法模式以返回特定类型?【英文标题】:Is is possible to mark specific methods paterns to return a specific type? 【发布时间】:2022-01-22 21:31:25 【问题描述】:

是否可以在 typescript 中定义一个仅应用于以某个单词开头并导致它们具有某种返回类型的方法的接口?我想到了类似的东西:

interface IPattern 
   [k: 'handle' + string]?: () => SomeClass

这样实现 IPatten 并具有以句柄开头的方法的类将被强制返回 SomeClass 对象,而其他方法则不会,例如:

class ForcedClass implements IPattern
   foo(): number; // ok
   handleFoo(): SomeClass; // ok
   handleBar(): number; // error

我知道可以将抽象类与我需要的所有方法一起使用,但是由于handle + something 的组合用于许多不同的实现,因此为每个实现创建一个抽象会很冗长;

【问题讨论】:

【参考方案1】:

您可以非常接近索引签名和模板文字类型:

interface IPattern 
   [k: `handle$string`]: () => SomeClass

class ForcedClass implements IPattern
   [k: `handle$string`]: () => SomeClass
   foo(): number  return 0  // ok
   handleFoo(): SomeClass  return "0 " ; // ok
   handleBar(): number return 0   // error



new ForcedClass()['handleBaz'](); // this is ok, because of the index signature
new ForcedClass().handleBaz(); // this is ok, because of the index signature

Playground Link

索引方法的问题在于,虽然类成员是针对它进行验证的,但这也意味着您可以使用符合 handle$string 模板文字类型的任何值进行索引,即使该成员实际上不是班级。

另一种选择是使用类型来验证类的实际键,而不添加索引签名:

type IPattern<T> = Record<Extract<keyof T, `handle$string`>, () => SomeClass> 

class ForcedClass implements IPattern<ForcedClass>
   foo(): number  return 0  // ok
   handleFoo(): SomeClass  return "0 " ; // ok
   handleBar(): number return 0   // error


new ForcedClass().handleBaz(); //error
new ForcedClass().handleFoo(); //ok

Playground Link

【讨论】:

感谢您的回答,我会关注有关索引签名的文档,顺便问一下,这些实现是否也适用于继承,或者每个子类都必须自己实现该模式?跨度> @LeoLetto 不幸的是,子类也需要自己实现这一点 好吧,我确实试过了,第一种方法是用抽象模式的子类来做的……第二种方法虽然看起来更优雅也不起作用,在这一点上我会留下来第一个,因为我可以抽象它以避免在每个子类中实现

以上是关于是否可以标记特定方法模式以返回特定类型?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在特定缩放级别上显示反应小叶标记?

支持 iOS 库中的特定设备方向 - 一处更改

JSDoc 快速上手

Azure 策略 - 拒绝使用特定标记创建资源

是否可以让 c# 使用大多数特定类型而不是基类型的方法重载?

是否可以在特定标记 android-maps-utils 上对相机进行去簇和居中?