You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The preceding (correctly) does not flag any issues. However, say I change the function call to:
configure({doSomethingSuper: true});
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:
Catching typos
(more importantly) Compile-time checking after a refactoring of "doSomethingSpecial" to be named something else
Perhaps some new syntax for enabling this mode would be useful. For example:
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:
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.
Would be interested to hear whether people prefer it on type declarations, in type position (or both), and why
My preference is for the sealed keyword to go on the type declaration. This fits in with our code-base where we have a single clearly defined object literal (say a "Point" type with x and y properties) that is used in multiple places. Permitting sealed in a type position seems to complicate matters a bit too much, IMO.
👍
definitely good and very useful feature suggestion. I had situations where this would find errors at compile time and I believe this what we strive for.
my opinion is the same as jbrantly:
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.
interfaceChatCardComponentProps{isActive?: boolean;}render(){// first argument must be of ChatCardComponentProps typeChatCardComponent({isActive: /* some condition */true})}
Later component's author can rename interface property from isActive to isSelected and there will be an issue. We can't catch it by compiler now. This is very common case in practice.
👍 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 function doWork(options: sealed MyOptions) {} is a good place for this.
Some ideas about naming: exact, strict or ! after the type function doWork(options: MyOptions!)
One thing to consider about moving the exact/strict specifier out of the type definition is that if you want the compiler to do the checking then, you'll have to add that specifier everywhere. example:
If we declare any parameter as exact/strict should you be able to pass it a variables of the same type that haven't been declared exact/strict? Same question with variable assignment.
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.
Activity
danquirk commentedon Aug 7, 2014
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:
Another alternative is that the type definition itself would be the place you specify this:
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.
jbrantly commentedon Aug 7, 2014
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.
NoelAbrahams commentedon Aug 11, 2014
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
sealedkeyword to go on the type declaration. This fits in with our code-base where we have a single clearly defined object literal (say a "Point" type with x and y properties) that is used in multiple places. Permittingsealedin a type position seems to complicate matters a bit too much, IMO.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.
mpawelski commentedon Aug 27, 2014
👍
definitely good and very useful feature suggestion. I had situations where this would find errors at compile time and I believe this what we strive for.
my opinion is the same as jbrantly:
s-panferov commentedon Sep 17, 2014
Another example is ReactJS's
propsobjects:Later component's author can rename interface property from
isActivetoisSelectedand there will be an issue. We can't catch it by compiler now. This is very common case in practice.👍 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
function doWork(options: sealed MyOptions) {}is a good place for this.Some ideas about naming:
exact,strictor ! after the typefunction doWork(options: MyOptions!)k4b7 commentedon Dec 2, 2014
One thing to consider about moving the
exact/strictspecifier out of the type definition is that if you want the compiler to do the checking then, you'll have to add that specifier everywhere. example:If we declare any parameter as
exact/strictshould you be able to pass it a variables of the same type that haven't been declaredexact/strict? Same question with variable assignment.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.
ahejlsberg commentedon Jul 21, 2015
Fixed in #3823.