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 15, 2019
1 parent 7d1d290 commit ed788bf
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 11 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
10 changes: 7 additions & 3 deletions packages/context/src/context-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,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 +88,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 ed788bf

Please sign in to comment.