Кажется, это возможно только с Отрицательными типами , который на момент написания этой статьи все еще оставался открытым. Единственный разумный способ приблизиться к этому на данный момент - это использовать тип объединения вместе с другим интерфейсом:
interface IBase {
"!prop1": string;
}
interface ITest extends IBase {
[key: string]: string | typeA | InterfaceB // etc...
}
И чем позже в ссылке на код, тем более строгим типом по мере необходимости:
function fn(arg: ITest): IBase | ITest {
if (arg["!prop1"]) {
return arg as IBase
} else {
return arg as ITest
}
}