-
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
negating type constraints #7993
Comments
You can already get the behavior you want today interface MyPromise {
resolve(): void;
}
function ignore(x: { resolve?: {'no promises allowed!': string}}) {
}
var x: MyPromise;
var y: string;
ignore(x); // Error
ignore(y); // OK |
function shallowCopy<a unlike number | string | null | undefined | Regex | Date>(value: a): a {
const result = {};
for (var key in value) {
if (value.hasOwnProperty(key)) {
result[key] = value[key];
}
}
return result;
} |
Seems like you're looking for #1809? |
function map<a, b unlike void>(values: a, map: (value: a) => b) : b[] { // <-- it doesn't make sense to map to void[]
} |
This issue is now awaiting more feedback. This means we'd like to hear from more people who would be helped by this feature, understand their use cases, and possibly contrast with other proposals that might solve the problem in a simpler way (or solve many other problems at once). If this feature looks like a good fit for you, please use the 👍 reaction on the original post. Comments outlining different scenarios that would be benefited from the feature are also welcomed. |
one more scenario: #8545 (comment) |
one more case for scenarios where, say, function asValid<a unlike null>(value: a, isValid: (value: a) => boolean) : a | null {
return isValid(value) ? value : null;
} |
similar but distinct // here we want to eliminate a chance of getting a default undefined from the JS runtime
export function tryAt<a unlike undefined>(values: a[], index: number): a | undefined {
return values[index];
} |
I'd propose less radical approach that already has all the machinery to be implemented: #9776 (comment) |
function String<a unlike string>(value: a): string {}
function Number<a unlike number>(value: a): number {} |
Negating types could allow unions with a catch-all member, without overshadowing the types of the known members. interface A { type: "a", data: number }
interface B { type: "b", data: string }
interface Unknown { type: string unlike "a"|"b", data: any }
type ABU = A | B | Unknown
var x : ABU = {type: "a", data: 5}
if(x.type === "a") {
let y = x.data; // y should be inferred to be a number instead of any
} |
|
@vvscode phenomenal. I used this to build a static destructuring exhaustiveness check: interface ExtraProps {
store: StoreType
otherProp: OtherType
}
type Not<T> = { [key in keyof T]?: never }
function someHOC<OwnProps>(Component: React.FC<OwnProps>) {
return ({ store, /* otherProp, */ ...ownProps }: ExtraProps & OwnProps) => (
<Provider store={store}>
<Component {...ownProps as Not<ExtraProps> /* error */ as OwnProps} />
</Provider>
)
} |
Unfortunately, it does not help too much with limiting choice. type DogHome = {
citizens: 'dog',
canDo: 'wow'
}
type CatHome = {
citizens: 'cat',
canDo: 'meuw'
}
type Not<T> = { [key in keyof T]?: never }
type UnknownHome = Not<DogHome> & Not<CatHome> & {
citizens: string;
canDo?: string;
phone?: string;
}
type AllHomes = DogHome | CatHome | UnknownHome;
const home: AllHomes = {
citizens: 'lonely' // Type '"lonely"' is not assignable to type '"dog" | "cat"'.
} |
Sometimes it's useful to put a limit on what a type parameter can be. In a way it is a counterpart of the
extends
constraint.Problem
Consider an example, a classic function that takes whatever and returns void:
However we must not apply this function to Promises, because it might get us a temporal leak if we do.
Unfortunately it is way too easy to get into a situation when a promise is passed to that function unintentionally as a result of refactoring:
Solution
The situation above could have been avoided if TypeScript allowed negating constraints:
The text was updated successfully, but these errors were encountered: