-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Closed
Labels
Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScriptAn idea for TypeScript
Description
In a type expression, I would like to be able to extend the implicitly known type of a value with specific type information.
The purpose is to get the most from the implicit type information and suplement it when some type information is missing.
Also, this will pull typescript even closer to ES6 by allowing common ES6 patterns like argument destructuring which results in the any type (where the type cannot currently be specified).
Syntax
// Like normal type information
const { req, opt = '', def = 'DEFAULT' }: { req: string, opt?: string, def?: string } = values;
// But 'extends' implicit typing
const { req, opt = '', def = 'DEFAULT' }: extends { req: string } = values;
The extends keyword would only modify the type information for the part of the type expression that was specified.
Useful Cases
Argument Destructuring with Type Information
Refer to: #7576 (comment)
And my comment there: #7576 (comment)
Full Typing (Absolutely no advantage from implicit type information)
export const Fun = ({ req, opt = '', def = 'DEFAULT' }: { req: string, opt?: string, def?: string }) => {
// ...
};
Current Best Solution
This uses Pure Implicit Typing, but it requires a default parameter that allows an unintended invalid call.
export const Fun = ({ req, opt = '', def = 'DEFAULT' } = { req: '' }) => {
// GOOD: All variables are implicitly typed
// ...
};
export const Fun_Call = () => {
// BAD: It is possible to call without arguments (i.e. pseudo-required)
Fun();
// GOOD: But if any object is given, it works right
Fun({ req: '' });
};
With Extends
export const Fun_extends = ({ req, opt = '', def = 'DEFAULT' }: extends { req: string }) => {
// ...
};
export const Fun_Call = () => {
// GOOD: This is not allowed
// Fun();
// GOOD: An object must be given with the correct typing
Fun({ req: '' });
};
Extending Return Values
Current Best Solution
// Complex Objects:
const ComplexReturn = () => { return { a: 'a', b: 'b', c: 'c' }; };
const obj = ComplexReturn();
const objWithD_typeofWithObject = obj as typeof obj & { d: string };
With Extends
// Complex Objects:
const ComplexReturn = () => { return { a: 'a', b: 'b', c: 'c' }; };
const objWithD_extends = ComplexReturn() as extends { d: string };
Checklist
Syntactic
- What is the grammar of this feature?
- 'extends' at the beginning of type expression like 'typeof' or 'keyof'
- Are there any implications for JavaScript back-compat? If so, are they sufficiently mitigated?
- No
- Does this syntax interfere with ES6 or plausible ES7 changes?
- No
Semantic
- What is an error under the proposed feature? Show many examples of both errors and non-errors
- The keyword would work in any type expression, just like 'keyof'
- How does the feature impact subtype, supertype, identity, and assignability relationships?
- For inheritance, it could be used to extend class members from their supertype
- How does the feature interact with generics?
- It would not change how the keyword is used with generics
Emit
- What are the effects of this feature on JavaScript emit? Be specific; show examples
- This is pure typing, it would be removed from runtime emit
- Does this emit correctly in the presence of variables of type ‘any’? Features cannot rely on runtime type information
- N/A
- What are the impacts to declaration file (.d.ts) emit?
- The keyword would need to by included in the declaration file typing information
- Does this feature play well with external modules?
- Yes
Compatibility
- Is this a breaking change from the 1.0 compiler? Changes of this nature require strong justification
- Unknown
- Is this a breaking change from JavaScript behavior? TypeScript does not alter JavaScript expression semantics, so the answer here must be “no”
- no
- Is this an incompatible implementation of a future JavaScript (i.e. ES6/ES7/later) feature?
- no
Other
- Can the feature be implemented without negatively affecting compiler performance?
- Yes
- What impact does it have on tooling scenarios, such as member completion and signature help in editors?
- It will provide a new type for that type expression
Aetherall, thalesmello and bitjson
Metadata
Metadata
Assignees
Labels
Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScriptAn idea for TypeScript