diff --git a/CHANGELOG.md b/CHANGELOG.md index e9f6fd8..0abf683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ - add `nonStrict` combinator ([#90](https://github.com/hoeck/simple-runtypes/pull/90)) - `nonStrict` creates a non-strict `record` runtype from a provided `record` runtype - a non-strict `record` runtype will ignore keys that are not specified in the original runtype's typemap - - non-strict `record` runtypes will replace `sloppyRecord` runtypes +- remove `sloppyRecord` + - replaced by `nonStrict`: `sloppyRecord(X)` -> `nonStrict(record(X))` + - fixes [#23](https://github.com/hoeck/simple-runtypes/issues/23) - fix: allow literal booleans as type-discriminators in discriminated unions, see [#98](https://github.com/hoeck/simple-runtypes/issues/98) ### 7.1.3 diff --git a/src/record.ts b/src/record.ts index 6c06a44..f3cb149 100644 --- a/src/record.ts +++ b/src/record.ts @@ -128,28 +128,3 @@ export function record< > { return internalRecord(typemap as any) } - -/** - * Like record but ignore unknown keys. - * - * Returns a new object that only contains the keys specified in the typemap. - * Additional keys are ignored. - * - * Keeps you save from unwanted propertiers and evil __proto__ injections. - */ -export function sloppyRecord< - T, - Typemap = { [K in keyof T]: Runtype | OptionalRuntype }, - OptionalKeys extends keyof Typemap = { - [K in keyof Typemap]: Typemap[K] extends OptionalRuntype ? K : never - }[keyof Typemap] ->( - typemap: Typemap, -): Runtype< - Collapse< - { [K in Exclude]: Unpack } & - { [K in OptionalKeys]?: Unpack } - > -> { - return internalRecord(typemap as any, true) -} diff --git a/test/sloppyRecord.test.ts b/test/sloppyRecord.test.ts deleted file mode 100644 index 0c2a1e7..0000000 --- a/test/sloppyRecord.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { expectAcceptValuesImpure, objectAttributes, st } from './helpers' - -describe('sloppyRecord', () => { - it('accepts simple records', () => { - const runtype = st.sloppyRecord({ - a: st.integer(), - b: st.string(), - }) - - expectAcceptValuesImpure(runtype, [{ a: 0, b: 'foo' }]) - }) - - it('accepts empty records', () => { - const runType = st.sloppyRecord({}) - - const value: {} = runType({}) - - expect(value).toEqual({}) - }) - - it('accepts records with optional values', () => { - const runtype = st.sloppyRecord({ - a: st.integer(), - b: st.optional(st.string()), - }) - - let value: { a: number; b?: string } - - value = runtype({ a: 0, b: 'foo' }) - expect(value).toEqual({ a: 0, b: 'foo' }) - - value = runtype({ a: 0, b: undefined }) - expect(value).toEqual({ a: 0, b: undefined }) - }) - - it('accepts nested records', () => { - const runtype = st.sloppyRecord({ - a: st.sloppyRecord({ - b: st.sloppyRecord({ - c: st.string(), - }), - }), - }) - - let value: { a: { b: { c: string } } } - - // eslint-disable-next-line prefer-const - value = runtype({ a: { b: { c: 'foo' } } }) - expect(value).toEqual({ a: { b: { c: 'foo' } } }) - }) - - it('returns runtypes values', () => { - const runtype = st.sloppyRecord({ - a: st.sloppyRecord({ - b: st.sloppyRecord({ - c: st.string({ trim: true }), // returns a modified string - }), - }), - }) - - let value: { a: { b: { c: string } } } - - // eslint-disable-next-line prefer-const - value = runtype({ a: { b: { c: ' foo ' } } }) - - expect(value).toEqual({ a: { b: { c: 'foo' } } }) - }) - - it('returns records with known keys', () => { - const runType = st.sloppyRecord({ - a: st.integer(), - b: st.string(), - }) - - expect(runType({ a: 1, b: 'foo', c: 'not-in-record-definition' })).toEqual({ - a: 1, - b: 'foo', - }) - }) - - it('ignores object attributes', () => { - const runType = st.sloppyRecord({ - x: st.number(), - }) - - objectAttributes - // JSON.parse bc the __proto__ attr cannot be assigned in js - .map((a) => ({ a, o: JSON.parse(`{"x": 1, "${a}": {"y":2}}`) })) - .forEach(({ a, o }) => { - const x = runType(o) - const y = runType(Object.assign({}, o)) - expect(x).not.toBe(o) - expect(x).toEqual({ x: 1 }) - expect(y).toEqual({ x: 1 }) - expect((x as any).y).toBeUndefined() - expect((y as any).y).toBeUndefined() - expect(Object.prototype.hasOwnProperty.call(x, a)).toBeFalsy() - expect(Object.prototype.hasOwnProperty.call(y, a)).toBeFalsy() - }) - }) -})