Skip to content
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 type assertions to consider typed index signatures #30342

Open
5 tasks done
zieka opened this issue Mar 12, 2019 · 2 comments
Open
5 tasks done

Allow type assertions to consider typed index signatures #30342

zieka opened this issue Mar 12, 2019 · 2 comments
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@zieka
Copy link

zieka commented Mar 12, 2019

Search Terms

interface, index, signature, typed, assertion, conversion, partial,

Suggestion

Currently type assertions do not seem to respect typed index signatures [key: string]: any; in interfaces or test for compatibility before attempting to convert.

I am proposing that type assertions would be able to convert this situation without error:

interface Test {
	a: string;
	b?: string;
	[key: string]: any;
}

const a = {b: 'b', c: 3 } as Test;

Use Cases

Currently to work around this I need to first create an intermediate variable that is typed as a Partial before making the assertion. I would prefer to just make the assertion.

Examples

This example above will error because {b: 'b', c: 3 } is missing property a

interface Test {
	a: string;
	b?: string;
	[key: string]: any;
}

const a = {b: 'b', c: 3 } as Test;

playground

If I remove c: 3 from the object then there is no error and a is no longer required:

interface Test {
	a: string;
	b?: string;
	[key: string]: any;
}

const a = {b: 'b' } as Test;

playground

Currently to workaround this an intermediate typed value can be used so the subtype is already confirmed before the assertion:

interface Test {
	a: string;
	b?: string;
	[key: string]: any;
}

const test: Partial<Test> = { b: 'b', c: 3 };
const a = test as Test

playground

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@DanielRosenwasser DanielRosenwasser added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Mar 12, 2019
@DanielRosenwasser
Copy link
Member

Some notes:

  • This could potentially open up a lot of problematic comparisons just because those types have index signatures.
  • It's wasn't immediately clear to me (i.e. at a glance) which direction of the comparability relationship this becomes more lenient for. It appears that the change would be Test ≤ { b: string, c: number } where refers to comparability).

@zieka
Copy link
Author

zieka commented Mar 19, 2019

Just revisiting this to clarify:
Given that we have a value V when asserting a type T for V then V should also be tested to see if it can be assigned to a Partial of T

(As seen in the workaround in the description)

Another possibly viable solution would be to just make an assertion on an object implicitly assert a partial of the type originally asserted.

So:

interface Test {
	a: string;
	b?: string;
	[key: string]: any;
}

const a = {b: 'b', c: 3 } as Test;

would implicitly be:

interface Test {
	a: string;
	b?: string;
	[key: string]: any;
}

const a = {b: 'b', c: 3 } as Partial<Test> as Test;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants