您可以使用conditional types 来获得类似的东西。例如:
interface CommonProps {
foo: string;
}
interface ManagedProps extends CommonProps {
managed: true;
managedOnlyProp: boolean;
}
interface ServerSideProps extends CommonProps {
serverSide: true;
serverOnlyProp: boolean;
}
type MappedProps<T> =
T extends { managed: true } ? ManagedProps :
T extends { serverSide: true } ? ServerSideProps :
CommonProps;
// Example function to test this:
declare function takeProps<T>(props: T & MappedProps<T>): void;
// And:
// This is OK, neither flag is present, so CommonProps are used:
takeProps({ foo: "" })
// This is an error. The managed flag is present, so we must also include the managed only props:
takeProps({ foo: "", managed: true }) // Gives error: Property 'managedOnlyProp' is missing in type '{ foo: string; managed: true; }' but required in type 'ManagedProps'.
// But this is okay, the flag is present but set to false...
takeProps({ foo: "", managed: false })
// And likewise for the serverSide versions:
takeProps({ foo: "", serverSide: true }) // Gives error: Property 'serverOnlyProp' is missing in type '{ foo: string; serverSide: true; }' but required in type 'ServerSideProps'.
takeProps({ foo: "", serverSide: true, serverOnlyProp: false }) // OK, no errors
takeProps({ foo: "", serverSide: false }) // OK, no errors
这是Playground Link。
请注意,这仅适用于每个标志。组合使用时,仍然可以传递一个无效的对象:
// This is wrong (missing serverOnlyProp) but no error is produced... :(
takeProps({foo: "", serverSide: true, managed: true, managedOnlyProp: false})