Type checking at runtime
Currently, we do some type checking at runtime, however, with typescript this could become not necessary. But I struggle to determine which could still be necessary. For example in backend.js we have this:
export function updateAccount(accountId, newFields) {
let error = hasForbiddenField(newFields, ['excludeFromBalance', 'customLabel']);
if (error) {
alert(`Developer error when updating an account: ${error}`);
return;
}
return buildFetchPromise(`api/accounts/${accountId}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newFields),
});
}
In case newFields
does not pass the test, updateAccount
returns undefined
, not a Promise. This leads to type mismatch. I guess we could not typechecking at runtime in this situation (because the data remains in the client).
However, in the models.js
the checks at runtime seems to be necessary to sanitize data. But this leads to mismatch in type definition. For example here: https://framagit.org/kresusapp/kresus/-/blob/master/client/models.js#L76
export class Account {
constructor(arg, defaultCurrency) {
...
this.lastCheckDate = assertHas(arg, 'lastCheckDate') && new Date(arg.lastCheckDate);
...
}
}
lastCheckDate
type is boolean | Date
, and this will have impact on the whole code. At the opposite, if we define lastCheckDate
as being a Date
, the current approach to test the data fetched from the server has to be changed (ie we could need to throw inside assertHas
.
So this ticket is more a discussion ticket for the coding strategy (all the problems highlighted here were raised by TSC, in the current JS code).