TypeScript cannot, in general, relate source objects with union-typed properties to arbitrary target unions of objects with non-union properties. For example, every value of type {x: A | B, y: C | D, z: E | F} should be assignable to the union {x: A, y: C, z: E} | {x: B, y: C, z: E} | {x: A, y: D, z: E} | {x: B, y: D, z: E} | {x: A, y: C, z: F} | {x: B, y: C, z: F} | {x: A, y: D, z: F} | {x: B, y: D, z: F}, but it's a lot of work for the type checker to verify that. If I made a mistake on one of those union members, or left one out, then it wouldn't be true anymore.
TypeScript 3.5 introduced some support for this type of checking, as implemented in microsoft/TypeScript#30779, but it's fragile and limited in scope.
It looks like you've hit one such limitation, as described in microsoft/TypeScript#58432, where the discriminant property of a discriminated union is optional.
According to a comment from @RyanCavanaugh, "there's almost always a better way to write the target type". So let's see if we can do that with your example.
Your original type is
type Props =
(
{ endpoint: 'constant-a' | 'constant-b'; property: object } |
{ endpoint?: 'constant-c'; property?: object }
) & (
{ isMulti: true; property2: object } |
{ isMulti?: false; property2?: object }
);
which is equivalent to a union of four members (distributing the intersection over the union).
And you're assigning a value of type {endpoint: 'constant-a' | 'constant-b' | 'constant-c'; property: object; property2: object} to it, which is assignable to none of the four union members of Props. Since we expect to be able to make such an assignment, we should try to see if we can take one of those union members and make it accept the assignment without also accepting unwanted assignments.
I'd suggest something like
type Props =
(
{ endpoint: 'constant-a' | 'constant-b' | 'constant-c'; property: object } |
{ endpoint?: 'constant-c'; property?: object }
) & (
{ isMulti: boolean; property2: object } |
{ isMulti?: false; property2?: object }
);
where I've widened some of union members to overlap other ones. I don't think this allows anything new: adding 'constant-c' as a possible endpoint to 'constant-a' | 'constant-b' only accepts things already accepted by the existing endpoint?: 'constant-c' member; and adding false as a possible isMulti to true only accepts things already accepted by the existing isMulti?: false member.
Now it works as you intend:
const endpoint: 'constant-a' | 'constant-b' | 'constant-c' = '' as any;
breaks({ endpoint, property: {}, property2: {} }); // okay
breaks({ endpoint: 'constant-c' }); // okay
breaks({ endpoint: 'constant-a' }); // error
So that answers the question as asked.
There might be some more general situation where you can't just rewrite the union without breaking a constraint, but if you plan to make a single assignment of a single source object with independent union-typed properties, then you can always find a way to make it work.
At the very least you should be able to add a union member corresponding to your assignment. That is, in general: if you have a value of type X and you're sure it should be assignable to type Y = A | B | C | D, but TypeScript doesn't think so, then you should be able to write type Y = A | B | C | D | X without changing things. After all, X is already supposed to be assignable to Y, so by adding X you're just being redundant, not permissive.
The only way it wouldn't work is if you either did conditional assignments, or a single assignment of dependent/correlated union-typed properties, where TypeScript can't keep track of the precise type of your object. (Like, if you wrote const v = Math.random() < 0.5 ? "a" : 1; const obj = {x:v, y:v}, then TypeScript would see this as {x: string | number; y: string | number} and not {x: string, y: string} | {x: number, y: number}.) But that doesn't seem to be what you're doing in this question, so it's probably out of scope here.
Playground link to code