microsoft / microsoft/TypeScript

Unexpected type assertion result

オープン
#32,653 コメント 2 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Needs Investigation
主要言語
Go
スター
111k
フォーク
14.4k
平均マージ
1日 19時間
マージ済み PR(30日)
117

説明

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)?

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

リンクされた repro リポジトリをクローンし、declarations を有効にして src/ 配下のファイルをコンパイルしてから、dist/index.d.ts と期待される出力を比較します。まず、src/index.ts の assertion と src/index.model.ts の Model 型について、declaration の生成を追跡します。生成された declaration が Model を保持し、dist/ からも有効な import path を使用していれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。