Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support typeof on object types #115

Open
SebastienGllmt opened this issue Nov 13, 2021 · 0 comments
Open

Support typeof on object types #115

SebastienGllmt opened this issue Nov 13, 2021 · 0 comments

Comments

@SebastienGllmt
Copy link

SebastienGllmt commented Nov 13, 2021

Description

Currently typescript-is fails with Failed to transform node when trying to index type using a generic type

This happens on latest master (0.19.0)

Issue reproduction

Both of these tests will fail

export const Status = {
    enable: 'enable',
    disable: 'disable'
} as const;

type StatusObject<Key extends 'enable' | 'disable'> = {
    status: (typeof Status)[Key];
};

describe('is', () => {
    describe('Accessing generic member of a type', () => {
        it('should return true for the right member', () => {
            assert.deepStrictEqual(is<StatusObject<'enable'>>({ status: Status.enable }), true);
        });
        it('should return false for the wrong member', () => {
            assert.deepStrictEqual(is<StatusObject<'enable'>>({ status: Status.disable }), false);
        });
    });
});

Investigation

Specific issue in this case

Currently, the code will throw on

if (!ts.isPropertySignature(valueDeclaration) && !ts.isMethodSignature(valueDeclaration)) {
because the type of the node is TypeParameter which doesn't match either case.

It looks like the cause of this issue is that TypeParameter contains both a valueDeclaration AND a type member

SymbolObject {
    ...
    valueDeclaration: NodeObject {
      ...
    },
    type: TypeObject {
      ...
    },
    target: SymbolObject {
      ...
    }
  }

General case

In fact, it looks like this case affects any usage of typeof. For example, the following code works just fine:

type Foo = { foo: 0 };
is<Foo>('foo'); // false

However, this fails

const obj = { foo: 0 };
is<typeof obj>('foo'); // throws an exception

Suggested fix

I think the fix is as simple as switching the priority of the condition here: check type first and THEN check valueDeclaration. This passes all existing tests and also fixes the two typeof issues I mentioned above.

Related issues

Possible #59 #97 #103

SebastienGllmt added a commit to SebastienGllmt/typescript-is that referenced this issue Nov 13, 2021
SebastienGllmt added a commit to SebastienGllmt/typescript-is that referenced this issue Nov 13, 2021
@SebastienGllmt SebastienGllmt changed the title Support type indexing with a generic type Support typeof on object types Nov 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant