woutervh- / typescript-is

MIT License
956 stars 35 forks source link

Investigation of Unbound Type Parameters #118

Open sgehly opened 2 years ago

sgehly commented 2 years ago

I was recently looking at #115 and I'm wondering if it may be possible to expand it into supporting nested & unbound parameter types. I know this is part of the "What it wont do" section, but it may be nice to investigate.

Here's a potential test that currently fails due to an unbounded type parameter:

import * as assert from 'assert';
import { assertType } from '../index';

type TestType = {
    name: string
}

type TestTypeTwo = {
    age: number
}

const deepDiveThree = <C>(body: unknown): C => {
    return assertType<C>(body)
}

const deepDiveTwo = <B>(body: unknown): B => {
    return deepDiveThree<B>(body)
}

const deepDive = <A>(body: unknown): A => {
    return deepDiveTwo<A>(body)
}

describe('is', () => {
    describe('Creating a generic assert type', () => {
        it('should not panic', () => {
            assert.deepEqual(deepDive<TestType>({ name: 'test' }).name, 'test')
            assert.deepEqual(deepDive<TestTypeTwo>({ age: 90 }).age, 90)
        });
    });
});

Unfortunately I don't have the technical know-how of typescript transformers to implement this myself yet, but I'm wondering if anyone had any pointers or if it's possible to resolve C up the chain through B and A to TestType and TestTypeTwo, while keeping in mind it may resolve to multiple different concrete types.