GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Unexpected type assertion result · Issue #32653 · microsoft/TypeScript

Unexpected type assertion result #32653

New issue
Copy link
New issue
Copy link
Open
Open
Unexpected type assertion result#32653
Copy link
Labels
Needs InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.
Milestone
Backlog

Description

@klemenoslaj
Klemen Oslaj (klemenoslaj)
opened on Aug 1, 2019
Issue body actions

TypeScript Version: 3.6.0-dev.20190801

Search Terms:

  • type assertion absolute import
  • type assertion import
  • type cast absolute import
  • type cast import
  • type assertion pick

Code

Repo: https://github.com/klemenoslaj/typescript-type-assertion

generated/types.d.ts

export interface TypeD {
  da: string;
  db: string;
  dc: string;
}

export interface Test { 
  a: string;
  b: string;
  c: string;
  d?: { __private: 'd' } & TypeD;
}

src/index.model.ts

import { Test } from 'generated/types';

type DType = NonNullable<Test['d']>;
export type Model = Pick<DType, keyof Exclude<DType, '__private'>>;

src/index.ts

import { Model } from './index.model';

export class A {
    value = <Model>{};
}

dist/index.model.d.ts

import { Test } from 'generated/types';
declare type DType = NonNullable<Test['d']>;
export declare type Model = Pick<DType, keyof Exclude<DType, '__private'>>;
export {};

dist/index.d.ts

export declare class A {
    value: Pick<{
        __private: "d";
    } & import("../generated/types").TypeD, "__private" | "da" | "db" | "dc">;
}

Expected behavior:

I would expect that dist/index.d.ts type definitions would result in:

import { Model } from './index.model';
export declare class A {
    value: Model;
}

In fact, this is the result of type definitions, if I change value = <Model>{}; to value: Model = <Model>{};.

Why doesn't typescript use Model directly when type asserting?

Actual behavior:

Results in:

export declare class A {
    value: Pick<{
        __private: "d";
    } & import("../generated/types").TypeD, "__private" | "da" | "db" | "dc">;
}

Playground Link:
I couldn't figure out how to compile declarations in playground, sorry :(

As an alternative please clone the following repo: https://github.com/klemenoslaj/typescript-type-assertion

Explanation:
This is quite a significant problem in monorepo environment.
What happens is that projects are compiled in the dist/ folder and they contain relative path like above (import("../generated/types")), which points from the src/ and not from dist/, effectively producing an error when projects start using one another.

Why doesn't typescript:

  • use the original path from the import (generated/types)?
  • use the type from assertion directly (Model)?
Reacted by Eugen Starov

Activity

  1. dragomirtitian commented on Aug 1, 2019

    @dragomirtitian
    Titian Cernicova-Dragomir (dragomirtitian)
    on Aug 1, 2019
    Contributor
    More actions

    A generally feature of type aliases is that they can be expanded transparently by the compiler, so probably when you use the assertion the compiler does not think it needs to keep the name around.

    Using an interface will probably get you the effect you desire:

    export interface Model extends  Pick<DType, keyof Exclude<DType, '__private'>> {}
  2. klemenoslaj commented on Aug 1, 2019

    @klemenoslaj
    Klemen Oslaj (klemenoslaj)
    on Aug 1, 2019
    Author
    More actions

    A generally feature of type aliases is that they can be expanded transparently by the compiler, so probably when you use the assertion the compiler does not think it needs to keep the name around.

    Using an interface will probably get you the effect you desire:

    export interface Model extends  Pick<DType, keyof Exclude<DType, '__private'>> {}

    Yes, that works 👍

    However, we cannot force people to use interfaces, therefore issue might still pop out causing frustrations, since it is not really straight forward problem.

    Is there any other way?

    EDIT

    Furthermore, if types are generated by 3rd party, we are even out of control, and using the type directly from generated/types will result in the same problem.

    I have update the repository accordingly:

    export class A {
        value1 = <Model>{};
        value2 = <Test['e']>{};
    }

    Results in

    export declare class A {
        value1: Pick<{
            __private: "d";
        } & import("../generated/types").TypeD, "__private" | "da" | "db" | "dc">;
        value2: {
            __private: "e";
        } & import("../generated/types").TypeD;
    }
  3. Ryan Cavanaugh (RyanCavanaugh)
    added
    BugA bug in TypeScriptA bug in TypeScript
    on Aug 1, 2019
  4. Ryan Cavanaugh (RyanCavanaugh)
    added this to the TypeScript 3.7.0 milestone on Aug 1, 2019
  5. Ryan Cavanaugh (RyanCavanaugh)
    assigned
    Ryan Cavanaugh (RyanCavanaugh)
    and
    Wesley Wigham (weswigham)
    and unassigned
    Ryan Cavanaugh (RyanCavanaugh)
    on Aug 1, 2019
  6. Ryan Cavanaugh (RyanCavanaugh)
    removed
    BugA bug in TypeScriptA bug in TypeScript
    on Aug 1, 2019
  7. Ryan Cavanaugh (RyanCavanaugh)
    unassigned
    Wesley Wigham (weswigham)
    on Aug 1, 2019
  8. Ryan Cavanaugh (RyanCavanaugh)
    removed this from the TypeScript 3.7.0 milestone on Aug 1, 2019
  9. Ryan Cavanaugh (RyanCavanaugh)
    added
    BugA bug in TypeScriptA bug in TypeScript
    on Aug 1, 2019
  10. Ryan Cavanaugh (RyanCavanaugh)
    added this to the TypeScript 3.7.0 milestone on Aug 1, 2019
  11. Ryan Cavanaugh (RyanCavanaugh)
    assigned
    Wesley Wigham (weswigham)
    on Aug 1, 2019
  12. Ryan Cavanaugh (RyanCavanaugh)
    modified the milestones: TypeScript 3.7.0, TypeScript 3.7.1 on Oct 14, 2019
  13. Ryan Cavanaugh (RyanCavanaugh)
    modified the milestones: TypeScript 3.7.1, TypeScript 3.8.0 on Oct 29, 2019
  14. Ryan Cavanaugh (RyanCavanaugh)
    modified the milestones: TypeScript 3.8.0, TypeScript 3.8.1 on Jan 8, 2020
  15. Ryan Cavanaugh (RyanCavanaugh)
    unassigned
    Wesley Wigham (weswigham)
    on Jan 24, 2020
  16. Ryan Cavanaugh (RyanCavanaugh)
    added
    Needs InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.
    and removed
    BugA bug in TypeScriptA bug in TypeScript
    on Jan 24, 2020
  17. Ryan Cavanaugh (RyanCavanaugh)
    modified the milestones: TypeScript 3.8.1, Backlog on Jan 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.

    Type

    No type

    Projects

    No projects

      Milestone

      • BacklogNo due date

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.