Skip to content

Commit

Permalink
fix(isolate): use TypeScript unknown to force casting types
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
staltz committed Feb 3, 2019
1 parent c2c2cbd commit ff698ce
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 13 deletions.
8 changes: 6 additions & 2 deletions isolate/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,17 @@ function isolateAllSinks<So extends Sources, Si>(

export type OuterSo<ISo> = {
[K in keyof ISo]: ISo[K] extends IsolateableSource
? any //FirstArg<IsolateableSource['isolateSource']>
? FirstArg<IsolateableSource['isolateSource']>
: ISo[K]
};

export type OuterSi<ISo, ISi> = {
[K in keyof ISo & keyof ISi]: ISo[K] extends IsolateableSource
? any // ReturnType<ISo[K]['isolateSink']> <- This does not work for e.g. @cycle/state
? (ReturnType<ISo[K]['isolateSink']> extends Stream<infer T>
? Stream<T>
: (ReturnType<ISo[K]['isolateSink']> extends Stream<any>
? Stream<unknown>
: unknown))
: ISi[K]
} &
{[K in Exclude<keyof ISi, keyof ISo>]: ISi[K]};
Expand Down
22 changes: 11 additions & 11 deletions isolate/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ describe('isolate', function() {
}

function MyDataflowComponent(
sources: {other: any},
sources: {other: unknown},
foo: string,
bar: string
) {
Expand All @@ -456,8 +456,8 @@ describe('isolate', function() {
);

assert.strictEqual(typeof scopedSinks, `object`);
scopedSinks.other.subscribe((x: Array<string>) => {
assert.strictEqual(x.join(), `foo,bar`);
scopedSinks.other.subscribe(strings => {
assert.strictEqual(strings.join(), `foo,bar`);
done();
});
});
Expand Down Expand Up @@ -492,11 +492,11 @@ describe('isolate', function() {
{other: new MyTestSource()},
`foo`,
`bar`
);
) as {other: Observable<Array<string>>};

assert.strictEqual(typeof scopedSinks, `object`);
scopedSinks.other.subscribe((x: Array<string>) => {
assert.strictEqual(x.join(), `foo,bar`);
scopedSinks.other.subscribe(strings => {
assert.strictEqual(strings.join(), `foo,bar`);
done();
});
});
Expand Down Expand Up @@ -531,11 +531,11 @@ describe('isolate', function() {
{other: new MyTestSource()},
`foo`,
`bar`
);
) as {other: Observable<Array<number>>};

assert.strictEqual(typeof scopedSinks, `object`);
scopedSinks.other.subscribe((x: Array<number>) => {
assert.strictEqual(x.join(), `123,456`);
scopedSinks.other.subscribe(nums => {
assert.strictEqual(nums.join(), `123,456`);
done();
});
});
Expand Down Expand Up @@ -624,15 +624,15 @@ describe('isolate', function() {
};
}

function MyDataflowComponent(sources: {other: any}) {
function MyDataflowComponent(sources: {other: unknown}) {
return {
other: of('a'),
};
}
const scopedMyDataflowComponent = isolate(MyDataflowComponent, `myScope`);
const scopedSinks = scopedMyDataflowComponent({other: driver()});
const i = 0;
scopedSinks.other.subscribe((x: any) => {
scopedSinks.other.subscribe(x => {
assert.strictEqual(x, 'a myScope');
done();
});
Expand Down

0 comments on commit ff698ce

Please sign in to comment.