microsoft / microsoft/TypeScript

Unable to infer method property but able to infer arrow function property

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

@weswigham がすでに取り組んでいます。

2021年5月13日 から。

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

説明

Bug Report

🔎 Search Terms

This issue came from StackOverflow question

🕗 Version & Regression Information

Since Object.fromEntries

⏯ Playground Link

Playground link with relevant code

💻 Code
const id = <T,>(x: T): T => x

const keys: string[] = []

/**
 * TS is unable to infer T generic argument of  fromEntries
 */
const fails = Object.fromEntries(keys.map(k => [
    k,
    id({ test() { } }) // <------ ERROR
]))

🙁 Actual behavior
const result: {
    [k: string]: T;
}
🙂 Expected behavior
const result: {
    [k: string]: {
        test(): void;
    };
}

I thought that it has smth to do with excess property checking, but it works if you replace id({ test() { } }) with id({ test:()=> { } })
Full list of workarounds:


/**
 * WORK
 */
const iter = keys.map(k => [
    k,
    id({ test() { } }) // ok
])
const obj1 = Object.fromEntries(iter)


const idResult = id({ test() { } })
const obj2 = Object.fromEntries(keys.map(k => [
    k,
    idResult
]))


const obj3 = Object.fromEntries(keys.map(k => [
    k,
    id({ test: () => { } }) // ok
]))


const obj4 = Object.fromEntries(
    keys.map<[string, { test(): void }]>((k) => [k, id({ test() { } })])
);


{
    interface Method {
        (): void;
    }
    const id = <T extends { [prop: string]: Method }>(x: T) => x;

    const keys: string[] = [];

    const obj = Object.fromEntries(keys.map((k) => [k, id({ test() { } })])); // ok

}

{
    type ArrowProp = () => any;
    const id = <T extends { [prop: string]: ArrowProp }>(x: T) => x;


    const obj = Object.fromEntries(keys.map((k) => [k, id({ test() { } })]));
}

{
    const id_ = <Prop, T extends Record<string, Prop>>(x: T) => x;
    // OR
    const id = <T extends object>(x: T) => x;
    const obj2 = Object.fromEntries(keys.map((k) => [k, id({ test() { } })]));
}

Playground

If I'm wrong and it is not a bug, could you please explain why TS is unable to infer method property?

I know that methods are bivariant, but I'm not sure if it has smth to do with current case

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

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

はじめの一歩

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

評価

この issue はまだ評価されていません。

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

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