【问题标题】:Template literal inference and narrowing in TypescriptTypescript 中的模板文字推断和缩小范围
【发布时间】:2022-01-21 17:46:46
【问题描述】:

我有以下代码:

export type EntityType = "foo" | "bar";
export interface Foo {
  id: `foo-${string}`;
}
export interface Bar {
  id: `bar-${string}`;
}

export type Ent<T extends EntityType> = T extends "foo" ? Foo : Bar;
export const resolve = <T extends EntityType>(id: `${T}-${string}`): Ent<T> => {
  if (id.startsWith("foo-")) {
    return { id: "foo-a" };
  }
  if (id.startsWith("bar-")) {
    return { id: "bar-a" };
  }
  throw new Error(`Unsupported entity type ${id}`);
};

return 语句抛出一个错误,上面写着:Type '{ id: "foo-a"; }' is not assignable to type 'Ent&lt;T&gt;'

出现这种情况是因为 TS 无法推断出 .startsWith("foo-") 实际匹配 Foo 接口,这是可以理解的。

有没有办法提示编译器,以便它可以正确推断和缩小预期的返回类型?现在这只有在我投射到任何时才有效:

if (id.startsWith("foo-")) {
  return { id: "foo-a" } as any;
}

【问题讨论】:

    标签: typescript type-inference template-literals


    【解决方案1】:

    也许你可以试试

    if (id.startsWith("foo-")) {
        return { id: "foo-a" } as Foo as Ent<T>;
    }
    if (id.startsWith("bar-")) {
        return { id: "bar-a" } as Bar as Ent<T>;
    }
    

    【讨论】:

    • 是的,我怀疑还有什么更好的。未解决的通用条件模板文字类型将在这里几乎不可能进行推理。
    • 这行得通,它不使用any
    猜你喜欢
    • 1970-01-01
    • 2017-08-12
    • 2013-05-21
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 2015-06-09
    相关资源
    最近更新 更多