Skip to content

Commit

Permalink
feat(build): add more TypeScript "strict" checks
Browse files Browse the repository at this point in the history
Enable all "strict" checks with the exception of
`strictPropertyInitialization` which would require significant changes.

The following additional checks are added:

- noImplicitThis
- alwaysStrict
- strictFunctionTypes

In the future, any checks added to TypeScript "strict" mode will be
automatically enabled for LoopBack projects too.
  • Loading branch information
bajtos committed Apr 11, 2019
1 parent 90117fa commit bfffe47
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 24 deletions.
9 changes: 7 additions & 2 deletions benchmark/src/benchmark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import * as byline from 'byline';
import {ChildProcess, spawn} from 'child_process';
import pEvent from 'p-event';
import pEvent, {Emitter} from 'p-event';
import {Autocannon, EndpointStats} from './autocannon';
import {Client} from './client';
import {scenarios} from './scenarios';
Expand Down Expand Up @@ -111,5 +111,10 @@ function startWorker() {

async function closeWorker(worker: ChildProcess) {
worker.kill();
await pEvent(worker, 'close');
await pEvent(
// workaround for a bug in pEvent types which makes them
// incompatible with "strictFunctionTypes"
worker as Emitter<[unknown]>,
'close',
);
}
7 changes: 4 additions & 3 deletions packages/build/config/tsconfig.common.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noImplicitAny": true,
"strictNullChecks": true,
"resolveJsonModule": true,
"strictBindCallApply": true,
"skipLibCheck": true,
"strict": true,

// FIXME(bajtos) LB4 is not compatible with this setting yet
"strictPropertyInitialization": false,

"lib": ["es2018", "esnext.asynciterable"],
"module": "commonjs",
Expand Down
32 changes: 16 additions & 16 deletions packages/context/src/context-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@
// License text available at https://opensource.org/licenses/MIT

import * as debugFactory from 'debug';
import {EventEmitter} from 'events';
import {promisify} from 'util';
import {Binding} from './binding';
import {BindingFilter} from './binding-filter';
import {Context} from './context';
import {
ContextEventType,
ContextObserver,
Subscription,
} from './context-observer';
import {Getter} from './inject';
import {ResolutionSession} from './resolution-session';
import {isPromiseLike, resolveList, ValueOrPromise} from './value-promise';
import { EventEmitter } from 'events';
import { promisify } from 'util';
import { Binding } from './binding';
import { BindingFilter } from './binding-filter';
import { Context } from './context';
import { ContextEventType, ContextObserver, Subscription } from './context-observer';
import { Getter } from './inject';
import { ResolutionSession } from './resolution-session';
import { isPromiseLike, resolveList, ValueOrPromise } from './value-promise';
const debug = debugFactory('loopback:context:view');
const nextTick = promisify(process.nextTick);

Expand Down Expand Up @@ -45,6 +41,9 @@ export class ContextView<T = unknown> extends EventEmitter
public readonly filter: BindingFilter,
) {
super();

// Workaround to pass TypeScript's "strictFunctionTypes" check
this.filter = filter as BindingFilter<unknown>;
}

/**
Expand Down Expand Up @@ -85,10 +84,11 @@ export class ContextView<T = unknown> extends EventEmitter
/**
* Find matching bindings and refresh the cache
*/
protected findBindings() {
protected findBindings(): Readonly<Binding<T>>[] {
debug('Finding matching bindings');
this._cachedBindings = this.context.find(this.filter);
return this._cachedBindings;
const found = this.context.find(this.filter);
this._cachedBindings = found;
return found;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function asLifeCycleObserver<T = unknown>(binding: Binding<T>) {
* Find all life cycle observer bindings. By default, a binding tagged with
* `CoreTags.LIFE_CYCLE_OBSERVER`. It's used as `BindingFilter`.
*/
export function lifeCycleObserverFilter(binding: Binding<unknown>): boolean {
export function lifeCycleObserverFilter(binding: Readonly<Binding>): boolean {
return binding.tagMap[CoreTags.LIFE_CYCLE_OBSERVER] != null;
}

Expand Down
10 changes: 8 additions & 2 deletions packages/repository/src/__tests__/unit/type-resolver.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
// License text available at https://opensource.org/licenses/MIT

import {expect} from '@loopback/testlab';
import {isBuiltinType, isTypeResolver, resolveType} from '../../type-resolver';
import {
isBuiltinType,
isTypeResolver,
resolveType,
TypeResolver,
} from '../../type-resolver';

class SomeModel {
constructor(public name: string) {}
Expand Down Expand Up @@ -60,7 +65,8 @@ describe('isTypeResolver', () => {

describe('resolveType', () => {
it('resolves the arg when the value is a resolver', () => {
const ctor = resolveType(() => SomeModel);
const resolver: TypeResolver<SomeModel> = () => SomeModel;
const ctor = resolveType(resolver);
expect(ctor).to.eql(SomeModel);

const inst = new ctor('a-name');
Expand Down

0 comments on commit bfffe47

Please sign in to comment.