question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: Supplementing Implicit Types

See original GitHub issue

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: https://github.com/Microsoft/TypeScript/issues/7576#issuecomment-198443953 And my comment there: https://github.com/Microsoft/TypeScript/issues/7576#issuecomment-340190459

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

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:3
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
aluanhaddadcommented, Oct 28, 2017

This is definitely the most interesting solution to the destructuring arguments typing problem that I’ve seen proposed.

0reactions
ricklovecommented, Mar 9, 2019

Ah, yeah I think ECMAscript destructured renaming is the worst design decision I have seen in modern languange design (especially when they knew very well that this would fly in the face of TypeScript).

Like what were they thinking…

‘’’ // Since everybody understands this well const x = { a : “value”, b: “value”, };

// And this is clear const {a,b} = x;

// And we need Default values const { a, b, c=42 } = x;

// What about renaming?

// This would be too easy const { a2:a, b2:b} = x;

// Oh, I know, let’s just reverse them because it makes sense - after all we have exactly no examples in the entire languange where a value assignment flows from left to right. So let’s just go in reverse from expected order for no good reason at all. const { a:a2, b:b2} = x;

// Not only will this send a clear sign to TypeScript that we can do whatever we feel like, it will bring back the good old days when everyone made fun of horrible JavaScript design decisions. ‘’’

I don’t think that was the exact thought process, but I just don’t get it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Elaboration with first-class implicit function types
We propose a new solution for elaborating first-class implicit functions, which is applicable to full dependent type theories and compares ...
Read more >
Implicit Type Conversions | Programming with OpenCL C
Implicit type conversion is an automatic type conversion done by the compiler whenever data from different types is intermixed.
Read more >
Budget Preparations | OSPI
Detailed data and tools to begin budgeting for the next school year: Budget Driver (John Jenft) sheet, K-3 Class Size Compliance, CEDARS Poverty...
Read more >
Supplemental Applications Proposing Labeling Changes for ...
This final rule provides that a supplemental application ... and guidance the types of supplements that should be filed to satisfy a ...
Read more >
Implicit Layers for Implicit Representations - NIPS papers
Additionally, as implicit representation networks are typically trained in large-batch settings, we propose to leverage the property of implicit layers to ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found