扩展打字稿界面+优化功能签名

时间:2018-08-31 12:32:38

标签: typescript

是否可以定义一个对象接口,然后扩展该接口,优化方法签名?

我希望将strictFunctionTypes设置为true

一个简单的例子:

interface Plugin {
    addListener: (eventName: string) => void;
}

interface FooPlugin extends Plugin {
    addListener: (eventName: 'fooChanged') => void;
}

在这里出现以下错误:

Interface 'FooPlugin' incorrectly extends interface 'Plugin'.
    Types of property 'addListener' are incompatible.
        Type '(eventName: "fooChanged") => void' is not assignable to type '(eventName: string) => void'.
            Types of parameters 'eventName' and 'eventName' are incompatible.
                Type 'string' is not assignable to type '"fooChanged"'.

这是一个更复杂的示例,显示了我最终想要做的事情:

export interface Plugin {
    addListener: (eventName: string, fn: Function) => void;
}

export interface FooPlugin extends Plugin {
    addListener: (eventName: 'fooInit', fn: (n: { i: boolean }) => void) => void;
    addListener: (eventName: 'fooDestroy', fn: (n: { d: number }) => void) => void;
}

2 个答案:

答案 0 :(得分:3)

我不太喜欢这种解决方案,但我想您需要使用它来键入非类型的库,以便您可以执行以下操作:

1)在插件界面中添加泛型

export interface Plugin<T, P> {
   addListener: (eventName: T, fn: (value: P) => void) => void;
}

2)然后创建一个类型,使您所有的侦听器都正确键入

export type FooPlugin = Plugin<'fooInit', { i: boolean }> & Plugin<'fooDestroy', { d: number 
}>

3)最后在您的代码中使用它

let plugin: FooPlugin = require("someLib");
plugin.addListener('fooInit', ({i}) => ...); 
plugin.addListener('fooDestroy', ({d}) => ...); 

答案 1 :(得分:2)

不管是好是坏,如果声明方法(而不是31 Aug 2018 11:23:23 [MessageBroker-2] ERROR springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator - Unhandled error for ExceptionWebSocketHandlerDecorator [delegate=LoggingWebSocketHandlerDecorator [delegate=SubProtocolWebSocketHandler[StompSubProtocolHandler[v10.stomp, v11.stomp, v12.stomp]]]] org.springframework.messaging.MessageDeliveryException: Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]; nested exception is org.springframework.security.access.AccessDeniedException: Access is denied at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:127) ~[spring-messaging-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:104) ~[spring-messaging-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.messaging.StompSubProtocolHandler.afterSessionEnded(StompSubProtocolHandler.java:643) ~[spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.clearSession(SubProtocolWebSocketHandler.java:482) ~[spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.afterConnectionClosed(SubProtocolWebSocketHandler.java:368) ~[spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.handler.WebSocketHandlerDecorator.afterConnectionClosed(WebSocketHandlerDecorator.java:85) ~[spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.afterConnectionClosed(LoggingWebSocketHandlerDecorator.java:72) ~[spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.afterConnectionClosed(ExceptionWebSocketHandlerDecorator.java:78) [spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.close(AbstractSockJsSession.java:216) [spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.close(AbstractSockJsSession.java:188) [spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService$1.run(TransportHandlingSockJsService.java:379) [spring-websocket-4.3.10.RELEASE.jar:4.3.10.RELEASE] at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-4.3.10.RELEASE.jar:4.3.10.RELEASE] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_181] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_181] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_181] )而不是函数值属性,这将起作用:

strictFunctionTypes