-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Allow stricter structural typing #391
Comments
We've definitely had this sort of request before, doesn't appear to have been logged on GitHub yet. The basic idea is to be able to specify a type that says 'you can/must have compatible properties x,y,z but you cannot have any additional properties' where currently TypeScript only allows a contract like 'you can/must have compatible properties x,y,z but you can have anything else too.' This is particularly problematic for options bags. Previous proposals have been along the lines of what you wrote: interface MyOptions {
isAwesome: boolean;
}
function doWork(options: sealed MyOptions) {}
doWork({ someUnknownProperty: 1 }); // error Another alternative is that the type definition itself would be the place you specify this: interface sealed MyOptions {
theOnlyAllowedProperty: string;
} but then you couldn't use this feature with object type literals, the type could only ever be used in a sealed fashion (maybe this is desirable), and you'd likely have to ensure sealed-ness was always matching between interface definitions. There're also questions of would your sealed-ness be inherited (I think not) and is it applied recursively to the types of your properties (doubtful). Would be interested to hear whether people prefer it on type declarations, in type position (or both), and why. Are there are common patterns you'd use this for besides options bags? Note: sealed is just one possible keyword, there're others and depending on the proposal sealed could actually be a bad choice due to the baggage it carries from other languages. |
To answer your question about common patterns, I think wrappers around interfaces (eg http://backbonejs.org/#Model-set) would benefit from this. You have a well defined interface for your model and anything outside of that interface is likely wrong. My preference would be allowing it on type declarations and in type position, but if I had to pick only one I would say in type position. |
I agree that this is a common source of errors - especially when refactoring code which results in properties being renamed.
My preference is for the See also the discussion "Should object literals with surplus properties be assignable to subtypes?" on the old codeplex site. I don't quite agree that this important piece of functionality should be left to a third party linting tool, as suggested in that discussion. |
👍 my opinion is the same as jbrantly:
|
Another example is ReactJS's interface ChatCardComponentProps {
isActive?: boolean;
}
render() {
// first argument must be of ChatCardComponentProps type
ChatCardComponent({
isActive: /* some condition */ true
})
} Later component's author can rename interface property from 👍 to the feature. ps. I think that interface definition is a wrong place for keyword because this issue is about usage of type in some known context. Type position like Some ideas about naming: |
One thing to consider about moving the
If we declare any parameter as I think the goal is avoid spelling mistakes when creating object literals. Already you can't add additional properties to objects of a specific interface if that interface doesn't already have it. Since object literals are the thing that's affected by the proposed change, maybe the new syntax should apply to the literal itself, e.g.
|
Fixed in #3823. |
Say I have the following:
The preceding (correctly) does not flag any issues. However, say I change the function call to:
This also does not flag any issues. I understand that in many (most?) cases this is the desired behavior, but in other cases it seems that a stricter matching (ie, you don't have to specify "doSomethingSpecial" but you can't specify anything else either) would be desirable. There are at least two instances that I can think of where this applies:
Perhaps some new syntax for enabling this mode would be useful. For example:
The text was updated successfully, but these errors were encountered: