From 139200e4fbcd365af3c9de3ee2e2a5ddb1dcc2b8 Mon Sep 17 00:00:00 2001 From: gcanti Date: Tue, 15 Jan 2019 21:13:17 +0100 Subject: [PATCH] Polish: make isIndexableCodec more strict --- CHANGELOG.md | 5 +++++ package.json | 2 +- src/index.ts | 11 +++++------ test/taggedUnion.ts | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a2dfaa8d..9a3807264 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ **Note**: Gaps between patch versions are faulty/broken releases. **Note**: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice. +# 1.6.2 + +- **Polish** + - make `isIndexableCodec` more strict (@gcanti) + # 1.6.1 - **Bug Fix** diff --git a/package.json b/package.json index 21d2eff3a..5cfcab124 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "io-ts", - "version": "1.6.1", + "version": "1.6.2", "description": "TypeScript compatible runtime type system for IO validation", "files": [ "lib" diff --git a/src/index.ts b/src/index.ts index afb7593a7..5f43982b8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1601,12 +1601,11 @@ const getCodecIndexRecord = (codec: Mixed, override: Mixed = codec): IndexRecord const isIndexableCodec = (codec: Mixed): boolean => { return ( - isInterfaceCodec(codec) || - isExactCodec(codec) || - isIntersectionCodec(codec) || - isUnionCodec(codec) || - isStrictCodec(codec) || - isRefinementCodec(codec) || + ((isInterfaceCodec(codec) || isStrictCodec(codec)) && + Object.keys(codec.props).some(key => isLiteralCodec(codec.props[key]))) || + ((isExactCodec(codec) || isRefinementCodec(codec)) && isIndexableCodec(codec.type)) || + (isIntersectionCodec(codec) && codec.types.some(isIndexableCodec)) || + (isUnionCodec(codec) && codec.types.every(isIndexableCodec)) || isRecursiveCodec(codec) ) } diff --git a/test/taggedUnion.ts b/test/taggedUnion.ts index 7cf9d43be..811f0d95b 100644 --- a/test/taggedUnion.ts +++ b/test/taggedUnion.ts @@ -297,4 +297,24 @@ describe('getIndexRecord', () => { kind: [['C2', C], ['D2', D]] }) }) + + it('should handle recursive types defined with a union containing a non indexable codec', () => { + // non indexable codec + const A = t.type({ + a: t.string + }) + + type A = t.TypeOf + + interface B { + modules: A | B + } + + const B = t.recursion('B', self => + t.type({ + modules: t.union([A, self]) + }) + ) + assert.deepEqual(t.getIndexRecord([B]), {}) + }) })