如何使用属性缩小类型

问题描述 投票:0回答:5

有没有办法在这个上下文中定义getInterface,以便res具有类型number

为了澄清:我没有尝试编写这些方法,我有一个环境,其中存在一个方法,根据parameters.type返回不同​​的对象,我正试图找到一种方法来键入它们

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()
typescript
5个回答
1
投票

虽然你的问题不是100%清楚,但在我的阅读中你会看到qazxsw poi采取什么类型并根据类型返回适当的值。

您可以使用重载或条件类型来执行此操作:

有重载:

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()

1
投票
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()

1
投票

谢谢你的帮助!我承认我的问题有点乱,我当然应该更清楚了。

无论如何,我设法得到了正确的打字 -

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> 将始终返回正确的接口,并且只要需要更改,就只能编辑一种联合类型


0
投票

它必须基本上处理getInterface({ type 'X' })功能

do_one()

0
投票

我们需要更清楚地理解类型,并且存在打字以避免编译期间的错误。编译后,最终结果将是纯javascript。

至于你的问题,只能使用或添加输入仅在编译期间将检查的条件。

动态打字是一个尚未解决的神话。

但是有一种方法可以使用getInterface(<someparam>):number{ do_one():number{ return 4; } } let res:number = one.do_one();

© www.soinside.com 2019 - 2024. All rights reserved.