microsoft / microsoft/TypeScript

Error on function return is less useful than it should be

未关闭
#63,357 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Domain: check: Contextual Types Possible Improvement
主要语言
Go
星标
111k
派生
14.3k
平均合并
2 天 4 小时
30 天内合并 PR
132

描述

🔍 Search Terms

"contextual typing of function return values" "function return error in the wrong place"

✅ Viability Checklist
⭐ Suggestion

Often when writing a function where the return type should be known, errors appear overly complicated and far away from their source.

type Ret = {a: number};
type Fn = () => Ret;


const issue: Fn = () => {
//    ^ it shows the error here: Type '() => { a: string; }' is not assignable to type '() => { a: number; }'.
    return {a: "25"};
//          ^ instead of here
};


// adding an explicit return type fixes it
const workaround1: Fn = (): Ret => {
    return {a: "25"};
//          ^ shows here: Type 'string' is not assignable to type 'number'.
};


// returning without a block body fixes it
const workaround2: Fn = () => ({a: "25"});
//                              ^ shows here: Type 'string' is not assignable to type 'number'.


// using a helper function fixes it
function inferRet<T>(arg: NoInfer<T>): T {
    return arg;
}
const workaround3: Fn = () => {
    return inferRet({a: "25"});
//                   ^ shows here: Type 'string' is not assignable to type 'number'.
};

Unfortunately, this would be a breaking change as it would cause some existing working code to now error, so it would have to be added under a compiler flag or wait for 7.0/8.0:

const breaking: Fn = () => {
    return {a: 25, b: 56};
//                 ^ previously, there would be no error here.
//                   with this change: Object literal may only specify known properties, and 'b' does not exist in type '{ a: number; }'.
};

Playground link

📃 Motivating Example
interface App {
    start: () => {
        title: {
            name: string,
        },
    },
}

export const app: App = {
    start: () => {
        return {
            title: {
                name: 25,
            },
        };
    },
};

Playground link

Previously, the error would show as:

10 |     start: () => {
         ~~~~~
Type '() => { title: { name: number; }; }' is not assignable to type '() => { title: { name: string; }; }'.
  Call signature return types '{ title: { name: number; }; }' and '{ title: { name: string; }; }' are incompatible.
    The types of 'title.name' are incompatible between these types.
      Type 'number' is not assignable to type 'string'.(2322)
input.tsx(2, 5): The expected type comes from property 'start' which is declared here on type 'App'

With this change, the error will show as:

13 |                name: 25,
                    ~~~~
Type 'number' is not assignable to type 'string'.(2322)
input.tsx(2, 5): The expected type comes from property 'name' which is declared here on type '{ name: string; }'

The second one is clearly easier to read and fix

💻 Use Cases
  1. What do you want to use this for?
    Interfaces that define functions with return types
  2. What shortcomings exist with current approaches?
    workaround 1: Explicitly setting the return type is annoying, and shouldn't need to be done when typescript clearly knows what it should be.
    workaround 2: Not using a block body is often not reasonable when computation needs to be done in the body of the function.
    workaround 3: You shouldn't need to define a helper function for this
  3. What workarounds are you using in the meantime?
    Every time I define a function where the return type could be inferred, I always specify it manually to make the errors easier to read.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从两个 Playground 示例开始,以重现当前的诊断,并比较报告的位置和消息。调查如何处理具有块体的函数的上下文返回类型,然后验证错误会移动到有问题的返回表达式,而不会改变文档中所述的多余属性行为。

由索引模型根据 Issue 内容生成。

评估

技术栈
typescript
领域
compilers
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
冷清
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。