Strict tsconfig

This commit is contained in:
Tony Garnock-Jones 2021-01-15 14:01:14 +01:00
parent d8a041a647
commit a5d4098e29
7 changed files with 52 additions and 40 deletions

View File

@ -206,7 +206,7 @@ export interface EncoderOptions {
}
function chunkStr(bs: Uint8Array): string {
return String.fromCharCode.apply(null, bs);
return String.fromCharCode.apply(null, bs as any as number[]);
}
export class Encoder {

View File

@ -36,16 +36,18 @@ Map.isMap = <K,V> (x: any): x is Map<K, V> => !!x?.[IsMap];
Object.defineProperty(Set.prototype, IsSet, { get() { return true; } });
Set.isSet = <T> (x: any): x is Set<T> => !!x?.[IsSet];
export function _iterMap<S,T>(i: Iterator<S> | undefined, f : (s: S) => T): IterableIterator<T> {
if (!i) return void 0;
export function _iterMap<S,T>(i: Iterator<S>, f : (s: S) => T): IterableIterator<T> {
const _f = (r: IteratorResult<S>): IteratorResult<T> => {
const { done, value } = r;
return { done, value: done ? void 0 : f(value) };
if (r.done) {
return { done: true, value: null };
} else {
return { done: false, value: f(r.value) };
}
};
return {
next: (v?: any): IteratorResult<T> => _f(i.next(v)),
return: (v?: any): IteratorResult<T> => _f(i.return(v)),
throw: (e?: any): IteratorResult<T> => _f(i.throw(e)),
return: (v?: any): IteratorResult<T> => _f(i.return?.(v) ?? { done: true, value: null }),
throw: (e?: any): IteratorResult<T> => _f(i.throw?.(e) ?? { done: true, value: null }),
[Symbol.iterator]() { return this; },
};
}
@ -56,9 +58,9 @@ export class FlexMap<K, V> implements Map<K, V> {
constructor(c: Canonicalizer<K>, items?: Iterable<readonly [K, V]>) {
this.canonicalizer = c;
this.items = new Map((items === void 0)
? void 0
: _iterMap(items[Symbol.iterator](), ([k, v]) => [this._key(k), [k, v]]));
this.items = (items === void 0)
? new Map()
: new Map(_iterMap(items[Symbol.iterator](), ([k, v]) => [this._key(k), [k, v]]));
}
_key(k: K): string {
@ -130,7 +132,7 @@ export class FlexMap<K, V> implements Map<K, V> {
{
const ks = this._key(key);
if (this.items.has(ks)) {
const oldValue = this.items.get(ks)[1];
const oldValue = this.items.get(ks)![1];
const newValue = f(oldValue);
if (newValue === void 0) {
this.items.delete(ks);
@ -165,9 +167,9 @@ export class FlexSet<V> implements Set<V> {
constructor(c: Canonicalizer<V>, items?: Iterable<V>) {
this.canonicalizer = c;
this.items = new Map((items === void 0)
? void 0
: _iterMap(items[Symbol.iterator](), (v) => [this._key(v), v]));
this.items = (items === void 0)
? new Map()
: new Map(_iterMap(items[Symbol.iterator](), (v) => [this._key(v), v]));
}
_key(v: V): string {
@ -181,7 +183,7 @@ export class FlexSet<V> implements Set<V> {
get(v: V): {item: V} | null {
const vs = this._key(v);
if (this.items.has(vs)) {
return {item: this.items.get(vs)};
return { item: this.items.get(vs)! };
} else {
return null;
}

View File

@ -4,9 +4,10 @@ import * as util from 'util';
import { Record, Bytes, Annotated, Set, Dictionary } from './values';
[Bytes, Annotated, Record, Set, Dictionary].forEach((C) => {
C.prototype[util.inspect.custom] = function (_depth: any, _options: any) {
return this.asPreservesText();
};
(C as any).prototype[util.inspect.custom] =
function (_depth: any, _options: any) {
return this.asPreservesText();
};
});
Record.fallbackToString = util.inspect;

View File

@ -183,13 +183,13 @@ export class Bytes {
static fromIO(io: string | BytesLike): string | Bytes {
if (typeof io === 'string') return io;
if (Bytes.isBytes(io)) return io;
if (io instanceof Uint8Array) return new Bytes(io);
return new Bytes(io);
}
static toIO(b : string | BytesLike): string | Uint8Array {
if (typeof b === 'string') return b;
if (Bytes.isBytes(b)) return b._view;
if (b instanceof Uint8Array) return b;
return b;
}
static concat = function (bss: BytesLike[]): Bytes {
@ -334,7 +334,7 @@ String.prototype.asPreservesText = function (): string {
Symbol.prototype.asPreservesText = function (): string {
// TODO: escaping
return this.description;
return this.description ?? '||';
};
Array.prototype.asPreservesText = function (): string {
@ -390,17 +390,20 @@ export interface Bytes {
for (const k of `entries every find findIndex forEach includes indexOf join
keys lastIndexOf reduce reduceRight some toLocaleString values`.split(/\s+/))
{
Bytes.prototype[k] = function (...args: any[]) { return this._view[k](...args); };
(Bytes as any).prototype[k] =
function (...args: any[]) { return this._view[k](...args); };
}
for (const k of `filter map slice subarray`.split(/\s+/))
{
Bytes.prototype[k] = function (...args: any[]) { return new Bytes(this._view[k](...args)); };
(Bytes as any).prototype[k] =
function (...args: any[]) { return new Bytes(this._view[k](...args)); };
}
for (const k of `reverse sort`.split(/\s+/))
{
Bytes.prototype[k] = function (...args: any[]) { return new Bytes(this._view.slice()[k](...args)); };
(Bytes as any).prototype[k] =
function (...args: any[]) { return new Bytes(this._view.slice()[k](...args)); };
}
Bytes.prototype[Symbol.iterator] = function () { return this._view[Symbol.iterator](); };
@ -417,6 +420,7 @@ export class Record extends Array<Value> {
// somewhat calling-convention-compatible. This is
// something that isn't part of the user-facing API.
super(label);
this.label = label; // needed just to keep the typechecker happy
return;
}
@ -426,7 +430,7 @@ export class Record extends Array<Value> {
Object.freeze(this);
}
get(index: number, defaultValue?: Value): Value {
get(index: number, defaultValue?: Value): Value | undefined {
return (index < this.length) ? this[index] : defaultValue;
}
@ -478,7 +482,7 @@ export class Record extends Array<Value> {
static makeBasicConstructor(label0: any, fieldNames: string[]): RecordConstructor {
const label = fromJS(label0);
const arity = fieldNames.length;
const ctor = (...fields: any[]) => {
const ctor: RecordConstructor = (...fields: any[]) => {
if (fields.length !== arity) {
throw new Error("Record: cannot instantiate " + (label && label.toString()) +
" expecting " + arity + " fields with " + fields.length + " fields");
@ -490,7 +494,7 @@ export class Record extends Array<Value> {
ctor.isClassOf = (v: any): v is Record => Record.isClassOf(constructorInfo, v);
ctor._ = {};
fieldNames.forEach((name, i) => {
ctor._[name] = function (r: any): Value {
ctor._[name] = function (r: any): Value | undefined {
if (!ctor.isClassOf(r)) {
throw new Error("Record: attempt to retrieve field "+label.toString()+"."+name+
" from non-"+label.toString()+": "+(r && r.toString()));
@ -525,7 +529,7 @@ export interface RecordConstructor {
(...fields: any[]): Record;
constructorInfo: RecordConstructorInfo;
isClassOf(v: any): v is Record;
_: { [getter: string]: (r: any) => Value };
_: { [getter: string]: (r: any) => Value | undefined };
}
export interface RecordConstructorInfo {
@ -569,15 +573,13 @@ export class Dictionary<T> extends FlexMap<Value, T> {
static fromJS(x: object): Dictionary<Value> {
if (Dictionary.isDictionary(x)) return x as Dictionary<Value>;
const d = new Dictionary<Value>();
for (let key in x) {
const value = x[key];
d.set(key, fromJS(value));
}
Object.entries(x).forEach(([key, value]) => d.set(key, fromJS(value)));
return d;
}
constructor(items?: Iterable<readonly [any, T]>) {
super(canonicalString, _iterMap(items?.[Symbol.iterator](), ([k,v]) => [fromJS(k), v]));
const iter = items?.[Symbol.iterator]();
super(canonicalString, iter === void 0 ? void 0 : _iterMap(iter, ([k,v]) => [fromJS(k), v]));
}
mapEntries<R>(f: (entry: [Value, T]) => [Value, R]): Dictionary<R> {
@ -633,7 +635,8 @@ export class Set extends FlexSet<Value> {
}
constructor(items?: Iterable<any>) {
super(canonicalString, _iterMap(items?.[Symbol.iterator](), fromJS));
const iter = items?.[Symbol.iterator]();
super(canonicalString, iter === void 0 ? void 0 : _iterMap(iter, fromJS));
}
map(f: (value: Value) => Value): Set {

View File

@ -22,7 +22,7 @@ describe('immutable byte arrays', () => {
expect(bs.findIndex((b) => b > 50)).toBe(-1);
});
it('should implement forEach', () => {
const vs = [];
const vs: number[] = [];
bs.forEach((b) => vs.push(b));
expect(fromJS(vs)).is(fromJS([10, 20, 30, 40]));
});

View File

@ -88,7 +88,11 @@ describe('common test suite', () => {
return encodeWithAnnotations(v);
}
const expectedValues = {
interface ExpectedValues {
[testName: string]: { value: Value } | { forward: Value, back: Value };
}
const expectedValues: ExpectedValues = {
annotation1: { forward: annotate(9, "abc"),
back: 9 },
annotation2: { forward: annotate([[], annotate([], "x")], "abc", "def"),
@ -123,7 +127,7 @@ describe('common test suite', () => {
describe(tName, () => {
const textForm = strip(annotatedTextForm);
const {forward, back} = (function () {
const entry = expectedValues[tName] || {value: textForm};
const entry = expectedValues[tName] ?? {value: textForm};
if ('value' in entry) {
return {forward: entry.value, back: entry.value};
} else if ('forward' in entry && 'back' in entry) {
@ -146,9 +150,9 @@ describe('common test suite', () => {
});
}
const tests = peel(TestCases._.cases(peel(samples))) as Dictionary<Value>;
const tests = peel(TestCases._.cases(peel(samples))!) as Dictionary<Value>;
tests.forEach((t0: Value, tName0: Value) => {
const tName = Symbol.keyFor(strip(tName0) as symbol);
const tName = Symbol.keyFor(strip(tName0) as symbol)!;
const t = peel(t0) as Record;
switch (t.label) {
case Symbol.for('Test'):

View File

@ -1,6 +1,7 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["es2019", "DOM"],
"declaration": true,
"baseUrl": "./src",
"rootDir": "./src",
@ -8,7 +9,8 @@
"declarationDir": "./lib",
"esModuleInterop": true,
"moduleResolution": "node",
"sourceMap": true
"sourceMap": true,
"strict": true
},
"include": ["src/**/*"]
}