【问题标题】: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 的组合用于许多不同的实现,因此为每个实现创建一个抽象会很冗长;

【问题讨论】:

    标签: typescript class ecmascript-6 interface


    【解决方案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 不幸的是,子类也需要自己实现这一点
    • 好吧,我确实试过了,第一种方法是用抽象模式的子类来做的……第二种方法虽然看起来更优雅也不起作用,在这一点上我会留下来第一个,因为我可以抽象它以避免在每个子类中实现
    猜你喜欢
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多