Skip to content

Commit 574c547

Browse files
committed
Upgrade to typescript 2.8.x
When consuming JSORM from a typescript 2.8 project there were some unexpected type errors. In order to resolve these, it was necessary to upgrade this to the newest version so to better detect the errors and fix them in this library.
1 parent dcd1e04 commit 574c547

14 files changed

+58
-48
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"ts-node": "4.0.1",
6868
"tslint": "5.9.0",
6969
"tslint-config-prettier": "1.6.0",
70-
"typescript": "2.6.2",
70+
"typescript": "2.8.3",
7171
"winston": "^2.3.1"
7272
},
7373
"dependencies": {

src/associations.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ const wasDestroyed = (model: JSORMBase) => {
2121
export class SingleAssociationBase<T extends JSORMBase> extends Attribute<T>
2222
implements Association {
2323
isRelationship: true = true
24-
jsonapiType: string
25-
typeRegistry: JsonapiTypeRegistry
26-
private _klass: typeof JSORMBase
24+
jsonapiType!: string
25+
typeRegistry!: JsonapiTypeRegistry
26+
private _klass!: typeof JSORMBase
2727

2828
constructor(options: AssociationRecord<T>) {
2929
super(options)
@@ -67,9 +67,9 @@ export class SingleAssociationBase<T extends JSORMBase> extends Attribute<T>
6767
export class HasMany<T extends JSORMBase> extends Attribute<T[]>
6868
implements Association {
6969
isRelationship: true = true
70-
jsonapiType: string
71-
typeRegistry: JsonapiTypeRegistry
72-
private _klass: typeof JSORMBase
70+
jsonapiType!: string
71+
typeRegistry!: JsonapiTypeRegistry
72+
private _klass!: typeof JSORMBase
7373

7474
constructor(options: AssociationRecord<T>) {
7575
super(options as any)

src/attribute.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ export type AttributeOptions = Partial<{
3030

3131
export class Attribute<T = any> {
3232
isRelationship = false
33-
name: string | symbol
33+
name!: string | symbol
3434
type?: T = undefined
3535
persist: boolean = true
36-
owner: typeof JSORMBase
36+
owner!: typeof JSORMBase
3737

3838
constructor(options: AttrRecord<T>) {
3939
if (!options) {

src/model.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export const applyModelConfig = <T extends typeof JSORMBase>(
121121
config = { ...config } // clone since we're going to mutate it
122122

123123
// Handle all JWT configuration at once since it's run-order dependent
124-
// We'll delete each key we encounter then pass the rest off to
124+
// We'll delete each key we encounter then pass the rest off to
125125
// a loop for assigning other arbitrary options
126126
if (config.credentialStorageBackend) {
127127
ModelClass.credentialStorageBackend = config.credentialStorageBackend
@@ -384,9 +384,9 @@ export class JSORMBase {
384384
stale: boolean = false
385385
storeKey: string = ""
386386

387-
@nonenumerable afterSync: (diff: Record<string, any>) => any | undefined
387+
@nonenumerable afterSync?: (diff: Record<string, any>) => any | undefined
388388
@nonenumerable relationships: Record<string, JSORMBase | JSORMBase[]> = {}
389-
@nonenumerable klass: typeof JSORMBase
389+
@nonenumerable klass!: typeof JSORMBase
390390

391391
@nonenumerable private _persisted: boolean = false
392392
@nonenumerable private _markedForDestruction: boolean = false
@@ -396,7 +396,7 @@ export class JSORMBase {
396396
string,
397397
JsonapiResourceIdentifier[]
398398
> = {}
399-
@nonenumerable private _attributes: ModelRecord<this>
399+
@nonenumerable private _attributes!: ModelRecord<this>
400400
@nonenumerable private _originalAttributes: ModelRecord<this>
401401
@nonenumerable private __meta__: any
402402
@nonenumerable private _errors: ValidationErrors<this> = {}
@@ -483,8 +483,9 @@ export class JSORMBase {
483483

484484
// fire afterSync hook if applicable
485485
let hasDiff = Object.keys(diff).length > 0
486-
let hasAfterSync = typeof this.afterSync !== "undefined"
487-
if (hasDiff && hasAfterSync) this.afterSync(diff)
486+
if (hasDiff && typeof this.afterSync !== "undefined") {
487+
this.afterSync(diff)
488+
}
488489
}
489490
return this._onStoreChange
490491
}

src/util/omit.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
export type Diff<T extends string, U extends string> = ({ [P in T]: P } &
2-
{ [P in U]: never } & { [x: string]: never })[T]
3-
export type Omit<T, K extends keyof T> = { [P in Diff<keyof T, K>]: T[P] }
1+
export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

src/util/validation-error-builder.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
JsonapiError,
55
JsonapiErrorMeta
66
} from "../jsonapi-spec"
7-
import { ValidationErrors } from "../validation-errors"
7+
import { ValidationErrors, ValidationError } from "../validation-errors"
88

99
export class ValidationErrorBuilder<T extends JSORMBase> {
1010
static apply<T extends JSORMBase>(
@@ -44,29 +44,28 @@ export class ValidationErrorBuilder<T extends JSORMBase> {
4444
this.model.errors = errorsAccumulator
4545
}
4646

47-
private _processResource(
48-
errorsAccumulator: ValidationErrors<T>,
47+
private _processResource<R extends JSORMBase=T>(
48+
errorsAccumulator: ValidationErrors<R>,
4949
meta: JsonapiErrorMeta,
5050
error: JsonapiError
5151
) {
5252
let attribute = this.model.klass.deserializeKey(meta.attribute)
53-
5453
errorsAccumulator[attribute] = {
55-
title: error.title,
56-
code: error.code,
54+
title: error.title as string,
55+
code: error.code as string,
5756
attribute: meta.attribute,
5857
message: meta.message,
5958
fullMessage: attribute === "base" ? meta.message : error.detail,
6059
rawPayload: error,
61-
} as any
60+
}
6261
}
6362

6463
private _processRelationship<R extends JSORMBase>(
6564
model: T,
6665
meta: JsonapiErrorMeta,
6766
err: JsonapiError
6867
) {
69-
let relatedObject = (<any>model)[meta.name]
68+
let relatedObject = model[meta.name]
7069
if (Array.isArray(relatedObject)) {
7170
relatedObject = relatedObject.find(r => {
7271
return r.id === meta.id || r.temp_id === meta["temp-id"]

src/util/write-payload.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class WritePayload<T extends JSORMBase> {
3232
const attrs: ModelRecord<T> = {}
3333

3434
this._eachAttribute((key, value) => {
35-
if (!this.model.isPersisted || this.model.changes()[key]) {
35+
if (!this.model.isPersisted || (<any>this.model.changes())[key]) {
3636
attrs[this.model.klass.serializeKey(key)] = value
3737
}
3838
})
@@ -241,13 +241,13 @@ export class WritePayload<T extends JSORMBase> {
241241
return false
242242
}
243243

244-
private _eachAttribute(callback: (key: keyof T, val: any) => void): void {
244+
private _eachAttribute<K extends keyof T>(callback: (key: K, val: T[K]) => void): void {
245245
const modelAttrs = this.model.typedAttributes
246246

247247
Object.keys(modelAttrs).forEach(key => {
248248
if (this.model.klass.attributeList[key].persist) {
249249
const value = modelAttrs[key]
250-
callback(key as keyof T, value)
250+
callback(key as K, value)
251251
}
252252
})
253253
}

src/validation-errors.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ export interface IValidationError<T extends JSORMBase> {
1212

1313
export class ValidationError<T extends JSORMBase>
1414
implements IValidationError<T> {
15-
code: string
16-
attribute: keyof ValidationErrors<T>
17-
title: string
18-
message: string
19-
fullMessage: string
20-
rawPayload: Record<string, any>
15+
code!: string
16+
attribute!: keyof ValidationErrors<T>
17+
title!: string
18+
message!: string
19+
fullMessage!: string
20+
rawPayload!: Record<string, any>
2121

2222
constructor(options: IValidationError<T>) {
2323
let key: keyof IValidationError<T>
@@ -33,7 +33,18 @@ export type ValidationErrors<T extends JSORMBase> = ErrorAttrs<
3333
keyof (Omit<T, keyof JSORMBase>)
3434
>
3535
export type ErrorAttrs<T extends JSORMBase, K extends keyof T> = {
36-
[P in K]?: ValidationError<T>
37-
} & { base?: ValidationError<T> }
36+
[P in K]?: IValidationError<T> | undefined
37+
} & {
38+
base?: IValidationError<T>
39+
/*
40+
* Index is necessary for typescript 2.8 compatibility. If we don't have
41+
* this, the `@Model()` decorator doesn't work. The error is that subclasses
42+
* of JSORMBase with additional fields aren't compabible since their error
43+
* objects aren't compatible. This is because ErrorAttrs<JSORMBase> doesn't
44+
* have a key like e.g. "title", whereas ErrorAttrs<Post> will. Adding an
45+
* index allowing undefined values will make these compatbile.
46+
*/
47+
[key: string] : IValidationError<T> | undefined
48+
}
3849

3950
let f = new JSORMBase()

test/integration/fetch-middleware.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ describe("fetch middleware", () => {
110110
if (url.indexOf("page") > -1) {
111111
shouldAbort = true
112112
}
113-
if (options.body && options.body.indexOf("abortme") > -1) {
113+
if (options.body && (options.body as string).indexOf("abortme") > -1) {
114114
shouldAbort = true
115115
}
116116

117117
if (shouldAbort) {
118118
throw ABORT_ERR
119119
}
120120

121-
options.headers["CUSTOM-HEADER"] = "whatever"
121+
;(options.headers as Headers)["CUSTOM-HEADER"] = "whatever"
122122
})
123123

124124
middleware.afterFilters.push((response, json) => {

test/integration/id-map.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ describe("ID Map", () => {
388388
book = new Book({ id: 1, author })
389389
book.isPersisted = true
390390
author.isMarkedForDisassociation = true
391-
;(await book.save({ with: "author" })) || this
391+
;(await book.save({ with: "author" }))
392392
})
393393

394394
it("is still in the store, but removed from the relation", async () => {

0 commit comments

Comments
 (0)