microsoft / microsoft/TypeScript

Issue with union type

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

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

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

説明

TypeScript Version: 3.7.5

Expected behavior:
Type of parameter qm in method Service.getItems should be union type assignable QueryModel<KeyToEntityMap<E>>

Actual behavior:

Argument of type 'QueryModel<KeyToEntityMap<E>>' is not assignable to parameter of type 'QueryModel<{ x: string; }> & QueryModel<{ y: string; }>'.
  Type 'QueryModel<KeyToEntityMap<E>>' is not assignable to type 'QueryModel<{ x: string; }>'.
    Type '{ x: string; }' is not assignable to type 'KeyToEntityMap<E>'.

Code

type Key = "a" | "b";
type KeyToEntityMap<E extends Key> =
    E extends "a" ? { x: string; } :
    E extends "b" ? { y: string; } :
    never;

class QueryModel<T>
{
    filters: [keyof T, string][] = [];
}

class Service<E extends Key>
{
    getItems(qm: QueryModel<KeyToEntityMap<E>>): KeyToEntityMap<E>[]
    {
        return [];
    }
}

type IServiceFactory = { [E in Key]: Service<E> };
class ServicesFactory implements IServiceFactory
{
    a: Service<"a"> = new Service<"a">();
    b: Service<"b"> = new Service<"b">();
}
const sf: IServiceFactory = new ServicesFactory();

class Same<E extends Key>
{
    fail(e: E)
    {
        let queryModel = new QueryModel<KeyToEntityMap<E>>();
        //Here getItems parameter gets wrong intersection type QueryModel<{ x: string; }> & QueryModel<{ y: string; }>
        let items: KeyToEntityMap<E> = sf[e].getItems(queryModel); 
    }
}

Output
"use strict";
class QueryModel {
    constructor() {
        this.filters = [];
    }
}
class Service {
    getItems(qm) {
        return [];
    }
}
class ServicesFactory {
    constructor() {
        this.a = new Service();
        this.b = new Service();
    }
}
const sf = new ServicesFactory();
class Same {
    fail(e) {
        let items = sf[e].getItems(new QueryModel());
    }
}

Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "useDefineForClassFields": false,
    "alwaysStrict": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "downlevelIteration": false,
    "noEmitHelpers": false,
    "noLib": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "esModuleInterop": true,
    "preserveConstEnums": false,
    "removeComments": false,
    "skipLibCheck": false,
    "checkJs": false,
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": false,
    "emitDecoratorMetadata": false,
    "target": "ES2017",
    "module": "ESNext"
  }
}

Playground Link: Provided

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

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

はじめの一歩

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

調査の方向性

提供された Playground リンクと、指定されたコンパイラーオプションでの最小限の TypeScript 再現コードから始めます。インデックス付きの Service ルックアップとジェネリックな条件型がどのようにチェックされるかを追跡し、報告された assignability エラーの回帰ケースを追加します。完了条件は、示されている戻り値の型を維持したまま、誤った intersection 型の診断なしに例の型チェックが通ることです。

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

評価

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

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

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