Вам необходимо преобразовать FooBarAction
в дискриминационный союз.На данный момент ваша версия FooBarAction
не очень строгая, в то время как type
должен быть одним из "FOO" | "BAR"
, а data
должен быть одним из FooBarTypeMap[FooBarTypes] = FooInterface | BarInterface
, между ними нет никакой связи.Таким образом, это может быть разрешено:
let o : FooBarAction2<FooBarTypes> = {
type: "BAR",
data: {} as FooInterface
}
Версия распознаваемого объединения будет выглядеть следующим образом:
export type FooBarAction = {
type: "FOO";
data: FooInterface;
} | {
type: "BAR";
data: BarInterface;
}
const doSomthingBasedOnType = (action: FooBarAction): void => {
switch (action.type) {
case "FOO":
FooAction(action);
}
};
// We use extract to get a specific type from the union
const FooAction = (action: Extract<FooBarAction, { type: "FOO" }>): void => {
//do something with action.data
};
Вы также можете создать объединение из объединения типов, используя распределенное поведение условных выражений.типы:
interface FooInterface { foo: number}
interface BarInterface { bar: number}
interface FooBarTypeMap {
FOO: FooInterface;
BAR: BarInterface;
}
type FooBarTypes = "FOO" | "BAR";
export type FooBarAction<T extends FooBarTypes> = T extends any ? {
type: T;
data: FooBarTypeMap[T];
}: never;
const doSomthingBasedOnType = (action: FooBarAction<FooBarTypes>): void => {
switch (action.type) {
case "FOO":
FooAction(action);
}
};
const FooAction = (action: FooBarAction<"FOO">): void => {
//do something with action.data
};