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

WIP use TypeScript unknown in isolate #873

Merged
merged 7 commits into from Feb 3, 2019
Merged

WIP use TypeScript unknown in isolate #873

merged 7 commits into from Feb 3, 2019

Conversation

staltz
Copy link
Member

@staltz staltz commented Jan 25, 2019

Do not merge yet

  • There exists an issue discussing the need for this PR
  • I added new tests for the issue I fixed or built
  • I used pnpm run commit instead of git commit

This PR just shows what kind of breaking changes would happen if we would introduce TypeScript's unknown instead of any. The purpose is to avoid sneaking any types that tend to virally propagate, and instead to use unknown which forces the developer to cast the type of some sinks returned from an isolated component. In other words, isolate would never give any types, it would force the developer to think about what type they expect.

Open for discussion before I do the following:

  • rebase/split commits into one commit per package
  • release new isolate, breaking change, with migration guide
  • update each package to use the new isolate

@@ -440,7 +440,7 @@ describe('isolate', function() {
}

function MyDataflowComponent(
sources: {other: any},
sources: {other: unknown},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even before this PR, this line should have been unknown.

But now, with this PR, this test does not pass (type check) with any (because scopedSinks.other would have been inferred as unknown, which would be a compile error a few lines below), so I had to change it to unknown.

@@ -492,11 +492,11 @@ describe('isolate', function() {
{other: new MyTestSource()},
`foo`,
`bar`
);
) as {other: Observable<Array<string>>};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Isolate were aware of Most.js and RxJS types of streams, we could support this test to type check without any changes. So we have to manually cast to RxJS's stream type here, otherwise it would be unknown.

@@ -531,11 +531,11 @@ describe('isolate', function() {
{other: new MyTestSource()},
`foo`,
`bar`
);
) as {other: Observable<Array<number>>};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same case as above.

@@ -624,15 +624,15 @@ describe('isolate', function() {
};
}

function MyDataflowComponent(sources: {other: any}) {
function MyDataflowComponent(sources: {other: unknown}) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same case as this comment

@@ -142,7 +142,7 @@ describe('withState', function() {
function Parent(sources: ParentSources): ParentSinks {
const childSinks = isolate(Child, {state: 'child'})(sources);
return {
state: childSinks.state,
state: childSinks.state as Stream<Reducer<Parent>>,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is a true example of an inference that we don't yet know how to support. Previously Isolate was inferring these cases as either Stream<Reducer<any>> or Stream<Reducer<{}>>, with this PR, the type is Stream<unknown> so it breaks on purpose unless the developer does a type cast, like we're doing here.

Copy link
Member

@jvanbruegge jvanbruegge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can find time for a quick review or some nerd sniping ;)

BREAKING CHANGE:
If you use JavaScript, there are no breaking changes. If you use
TypeScript, then from now onwards isolate() returns sink types that are
never type "any", but instead returns "unknown". Often it may infer the
correct type, but when it cannot infer the type, it will return
"unknown" which means you are forced to type cast it to the correct
type. This is better than "any", because "any" is like JavaScript and
gives little type safety.
@staltz staltz merged commit 990755f into master Feb 3, 2019
@staltz staltz deleted the isolate-unknown branch February 3, 2019 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants