如何使用属性缩小类型



在此上下文中有什么方法可以定义 getInterface,以便res具有类型number

要澄清:我不是要编写这些方法,我有一个环境,其中存在一种方法,该方法根据参数返回不同的对象。

interface A {
  tag: 'a'
  do_one: () => number;
}
interface B {
  tag: 'b'
  do_one: () => string;
}
type Interface = A | B
let one = getInterface({ type: 'a' })
let res = one.do_one()

虽然您的问题不是100%清楚,但在我阅读您的getInterface中,要采用该类型并根据该类型返回适当的价值。

您可以使用过载或条件类型进行此操作:

超载:

type Interface = A | B
function getInterface(v: { type: 'a' }): A
function getInterface(v: { type: 'b'}): B 
function getInterface(v: { type: 'b'} | { type: 'a'}): A | B {
    return null!
}
let one = getInterface({ type: 'a' })
let res = one.do_one()

有条件类型

interface A {
    tag: 'a'
    do_one: () => number;
}
interface B {
    tag: 'b'
    do_one: () => string;
}
type Interface = A | B
type GetJustTypes = Interface extends infer I ? I extends { tag: infer U } ? { tag: U } : never : never
function getInterface<T extends GetJustTypes>(v: T): Extract<Interface, T>
function getInterface(v: { tag: 'b' } | { tag: 'a' }): A | B {
    return null!
}
let one = getInterface({ tag: 'a' })
let res = one.do_one()
declare function getInterface(arg: { type: 'a' }): A;
declare function getInterface(arg: { type: 'b' }): B;
let one = getInterface({ type: 'a'} )
let res = one.do_one()  // res is a number

谢谢您的所有帮助!我承认我的问题有点混乱,我绝对应该更清楚。

无论如何,我设法获得了正确的键入 -

type FilterTag<T, U> = T extends { tag: U } ? T : never
type Interface<T> = FilterTag<A | B, T>
declare function getInterface<T extends string>(params: { type: T }): Interface<T>

这意味着getInterface({ type 'X' })始终将返回正确的接口,只要需要更改

,就只有一种联合类型要编辑

它必须与do_one()函数进行处理

getInterface(<someparam>):number{
   do_one():number{
      return 4;
   }
}
let res:number = one.do_one();

我们需要更清晰地了解键入,存在分型以避免在编译时间期间出现错误。编译后,最终结果将为纯JavaScript

至于您的问题,只能使用>或 | 条件添加键入。

动态键入是一个尚未解决的神话。

但是有一个可以使用的方法实例。

最新更新