У меня есть проблема, когда я пытаюсь создать интерфейс для общих модулей в TypeScript, который для целей этого вопроса предположим, имеет следующую форму:
interface A {
x: string;
y: { [name: string]: (...args: any) => {type: string; payload?: any} };
z?: () => any
}
Цель этого интерфейса - два-fold:
- Для человека, производящего модуль, я хочу, чтобы он мог знать, что то, что он создает, соответствует A.
- Для человека, потребляющего модуль,Я хочу, чтобы они могли иметь максимально возможную типизацию.
Например, если бы у меня было:
const bar = {
x: 'hello',
y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}
Обратите внимание на отсутствие ссылки на интерфейс A
.
Если бы я потом набрал: bar.
Я бы понял, что у него есть свойства x
и y
.Более того, после ввода bar.y.
мне будет предложено указать, что существует world
и тип функции, связанный с ним.
Однако, если я добавлю A
:
const bar: A = {
x: 'hello',
y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}
это помогает в случае, если кто-то случайно добавил неправильное свойство, такое как:
const bar: A = {
iDontBelong: true, // wrong
x: 'hello',
y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}
или даже
const bar: A = {
x: 5, // wrong
y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}
Теперь проблема заключается в том, что если кто-то импортирует bar
и наберет bar.
они будут получать предложения, которые непосредственно для интерфейса A
.Он теряет знание о том, что bar
имеет только x
и y
(и не z
), а также теряет информацию о специфическом типе y
, означающем, что он даже не знает, что world
существуетна y
.
Есть ли способ заставить обе эти вещи существовать одновременно?