From 179e6d5fa58076e5e2921b0cdb7870e3c95faafe Mon Sep 17 00:00:00 2001 From: David Furey Date: Wed, 10 Feb 2021 18:07:14 +0000 Subject: [PATCH] Add functionality to capture type parameters in interfaces Based on commit 6b1a425958b505f7d42f5318f764a3b1266a614d --- src/transform-inline/visitor-utils.ts | 13 +++++++++++++ test/issue-86.ts | 25 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 test/issue-86.ts diff --git a/src/transform-inline/visitor-utils.ts b/src/transform-inline/visitor-utils.ts index 76b6633..28325db 100644 --- a/src/transform-inline/visitor-utils.ts +++ b/src/transform-inline/visitor-utils.ts @@ -138,6 +138,19 @@ export function getTypeReferenceMapping(type: ts.TypeReference, visitorContext: if (tsutils.isInterfaceType(type.target)) { const baseTypes = visitorContext.checker.getBaseTypes(type.target); for (const baseType of baseTypes) { + if (baseType.aliasTypeArguments && visitorContext.previousTypeReference !== baseType && (baseType as ts.TypeReference).target) { + const typeReference = baseType as ts.TypeReference + if (typeReference.aliasTypeArguments !== undefined && typeReference.target.aliasTypeArguments !== undefined) { + const typeParameters = typeReference.target.aliasTypeArguments; + const typeArguments = typeReference.aliasTypeArguments; + for (let i = 0; i < typeParameters.length; i++) { + if (typeParameters[i] !== typeArguments[i]) { + mapping.set(typeParameters[i], typeArguments[i]); + } + } + } + } + if (tsutils.isTypeReference(baseType) && baseType.target.typeParameters !== undefined && baseType.typeArguments !== undefined) { const typeParameters = baseType.target.typeParameters; const typeArguments = baseType.typeArguments; diff --git a/test/issue-86.ts b/test/issue-86.ts new file mode 100644 index 0000000..5b954fe --- /dev/null +++ b/test/issue-86.ts @@ -0,0 +1,25 @@ +import * as assert from 'assert'; +import { is } from '../index'; + +/* https://github.com/woutervh-/typescript-is/issues/86 */ + +type Y = { + field: T; +} + +interface X extends Y { +} + +describe('is', () => { + describe('Interface extending a parameterised type alias', () => { + it('should return true for object with field type string', () => { + assert.deepStrictEqual(is({ field: 'some-string' }), true); + }); + it('should return false for object with field type number', () => { + assert.deepStrictEqual(is({ field: 0 }), false); + }); + it('should return false for object without field', () => { + assert.deepStrictEqual(is({}), false); + }); + }); +});