-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Partial object application/"outersection" types #6895
Comments
Here's another use case:
The real world use case I have for this is that I want to define a React component that takes all props that an
In some cases it can be solved by creating a new base type without the properties that differ, but that's not really possible if the type isn't defined in your own code. |
I wonder if 'outersections' could also be useful in making type guards more general (i.e. not just always starting from a union type and removing things from it). E.g.: interface Thing {a;b;c;then;e;f}
interface Thenable {then}
function isThenable(obj: any): obj is Thenable {
return 'then' in obj;
}
function foo(x: Thing) {
if (isThenable(x)) {
x.then(...)
}
else {
// here type of x is Thing - Thenable
x.a // OK
x.then // ERROR
}
} |
I posted #7423 and was linked to here. Indeed this is very common. Particularly for decorators or component's like |
This would be a huge amount of work (basically the same amount as intersection or union types were) for a much smaller set of scenarios, but it's still something we want to address at some point. Likely if/when we have a general notion of type operators, this would be the sort of thing that they would handle. If you run into other scenarios where this would be useful, please do leave a comment so we can prioritize accordingly. |
I came across this when working with React also. In my situation, I needed to do something like this: interface A extends B, C { }
interface B { field: SomeType; ... }
interface C { field: SomeOtherType; ... } Since I understand that this is somewhat an untypical scenario and would be a lot of work on the tsc end, but an "outersection" or "subtraction" type would be neat! |
Seems like basic type outersection is already partially implemented when destructuring objects with spreads: type TProps = {
foo: string,
bar: any,
name: number
};
declare const props: TProps;
const {
foo, //string
...rest ////type is correctly inferred - {bar: any, name: number}
} = props;
//type of rest can be treated as an outersection of TProps and {foo: TProps['foo]} Can this logic be reused for deconstructuring types?
|
Another use case for this (in particular, permitting subtraction of literals) would be to enable the following:
which could be useful for typing a reasonably large class of objects. |
I've searched for how to do this and if there are any open issues requesting it, but couldn't find anything. Apologies if I didn't search enough and there is an issue somewhere.
What I'd like to do is essentially the opposite of intersection types. I want to subtract one type from another, and get the delta as a new type.
Here's a code example:
The type annotation
z: X - Y
is something I just made up, but what it does is almost the opposite orz: X & Y
.The real world use case I have for this is that in the React world, it's very common to wrap components in other components. I might have one component which expects five props, but when I use that component I don't want to have to specify all of them. Instead I would wrap that component in another component that would pass some of the props to the inner component. And I would like the wrapping component to be typed as a component that expects the other props.
Here's a simple example:
A question is what happens if the subracting type isn't a strict subset of the other type. I'd say that it would be a compile error and that the right side type has to be a subset of the left type.
Another thing is that it shoould be composable. I could say
x: X - Y - Z
which would subtract left to right like thisx: ((X - Y) - Z)
.The text was updated successfully, but these errors were encountered: