У меня в приложении есть система для IPC (Inter Process Communications). Все виды комуникации разделены по разным сервисам. У меня описаны интерфейсы для каждого сервиса, есть словарь всех сервисов и функция которая по названию, возвращает конкретный сервис.
Упродённо это выглядит примерно так:
// Интерфейс для одного сервиса
interface Service_FOO {
methodFoo: () => void
}
// Интерфейс для другого сервиса
interface Service_BAR {
methodBar: () => void
propertyBar: boolean // <-- Должно привести к ошибке
}
// Словарь всех сервисов и их названий
interface ServiceMap {
'Service_FOO': Service_FOO
'Service_BAR': Service_BAR // <-- Или привести к ошибке здесь
}
// Функцыя которая создаёт и возвращает сервис
function createClient<T extends keyof ServiceMap>(name: T) : ServiceMap[T] {
return {} as ServiceMap[T]
}
// Пользовательский код
const serviceFoo = createClient('Service_FOO')
serviceFoo.methodFoo()
const serviceBar = createClient('Service_BAR')
serviceBar.propertyBar // Приведёт к ошибке в рантайме
Playground
Проблема в том, что из-за особенностей реализации
createClient
все сервисы могут иметь только методы. Отсюда мой вопрос:
Как можно ограничить сам интерфейс чтобы он содержал только методы? Или как ограничить словарь ServiceMap
чтобы он мог содержать только интерфейсы в которых только методы?
Я попытался сделать вот так:
interface Service_FOO extends Record<string, () => void> {
methodFoo: () => void
}
interface Service_BAR extends Record<string, () => void> {
methodBar: () => void
// @ts-expect-error
propertyBar: boolean
}
// Class 'FOO' incorrectly implements interface 'Service_FOO'.
// Index signature is missing in type 'FOO'.
class FOO implements Service_FOO {
methodFoo() {}
}
Playground
И я действительно получаю ошибку типов в интерфейсе
Service_BAR
, но в месте с этим я начал получать ошибку в классе
FOO
:
Class 'FOO' incorrectly implements interface 'Service_FOO'.
Index signature is missing in type 'FOO'.