Skip to content

Different types in declaration and original when filtering union of objects by enum property #40036

@JakubKoralewski

Description

@JakubKoralewski

TypeScript Version: 3.9.7

Search Terms:

declaration extends typescript different type
declaration enum property never
typescript type is not assignable to type never

Code

I believe the bug requires imports to be reproduced.

some1.ts
import { TYPE } from './index'

export type API = {
        PATH: 'some1';
	TYPE: TYPE.BINARY;
}
some2.ts
import { TYPE } from './index'

export type API = {
        PATH: '/some2';
	TYPE: TYPE.JSON;
}
// import {some1} from './some1';
// import {some2} from './some2';
export declare const enum TYPE {
  BINARY = 0,
  JSON = 1
}
declare type some = some1 | some2;
declare type FilterApisByType<R extends TYPE, T = some> = T extends {
    TYPE: R;
} ? T : never;
export declare type test = FilterApisByType<TYPE.BINARY>;

I'm filtering a union of objects by the objects' property. So in the above example the some1 variable has a TYPE of TYPE.BINARY while some2 has a TYPE of TYPE.JSON. The correct behavior would be for the resulting test type to be only some1, which its is when checking from index.ts, but when hovering over the same variable in index.d.ts the type gets resolved to never.

I'm not using any declares in the original code and the issue persists. Looks like the MakeApi type is not necessary. I removed it and the issue persists. I tried to filter by another property which didn't hold enums and it seemed to work; the issue was gone. Seems like the filtered property has to have enum values. It made no difference if the enum was const or not.

Expected behavior:
index.ts:
image

Actual behavior:
index.d.ts:
image

Playground Link:
https://codesandbox.io/s/eloquent-kalam-spyyb?file=/index.ts
I saved this sandbox as zip, then opened the IDE in the src directory.

Related Issues:
N/A

What's interesting is that if I manually change the index.d.ts to instead of filtering originally like this: FilterApisByType<TYPE.BINARY> to be filtering as the actual value of the enum (FilterApisByType<0>), then it works.

EDIT:

I tried to replicate the issue in VS Code to make sure it was not Intellij's fault, and I was able to repeat the issue:

index.ts:
image

index.d.ts:
image

EDIT2:

I'd love to get some info about some sort of temporary workaround for this issue as it is breaking my project. I can't import the .ts files directly because the exported types are imported as a npm module with a weird webpack configuration that throws an

error

Module parse failed: The keyword 'enum' is reserved (3:13)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. S
ee https://webpack.js.org/concepts#loaders

| import { MakeApi, RESULT_TYPE } from '../index';
|
> export const enum RESULT {
|       OK,
|       INVALID_DATA,
if the file is imported directly without having run `tsc` beforehand 😕

On an unrelated note I found a workaround for the webpack bug :hooray:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs More InfoThe issue still hasn't been fully clarified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions