繁体   English   中英

Function 类型的可区分联合?

[英]Discriminated Unions of Function Types?

我似乎无法弄清楚如何区分 function 类型的受歧视工会的成员。 请参见以下示例:

type _NumFunc = (n: number) => string;
type _StrFunc = (s: string) => string;
interface NumFunc extends _NumFunc { __type: 'NumFunc'; }
interface StrFunc extends _StrFunc { __type: 'StrFunc'; }
type Func = NumFunc | StrFunc;

let myNumFunc = ((n: number) => `Hello x${n}!`) as NumFunc;
let myStrFunc = ((s: string) => `Hello, ${s}!`) as StrFunc;

let funcGen = (n: number): Func => n % 2 == 0 ? myNumFunc : myStrFunc;

for (let i = 0; i < 2; i++)
{
    let func = funcGen(i);
    switch (func.__type)
    {
    case 'NumFunc':
        console.log(func(3));
        break;
    case 'StrFunc':
        console.log(func('World!'));
        break;
    default:
        console.error(func);
        console.error('How did this happen?');
        break;
    }
}

我预计这个程序的 output 应该是:

你好 x3!

你好世界!

但是,如果您运行此代码,您会看到每次迭代都会调用默认情况。 简单地记录func将显示 function object,但尝试访问__type上的 __type 会引发错误,指出func的类型never 为什么这种方法不起作用,是否有任何方法允许使用 function 类型的可区分联合?

好问题。 我们需要了解 TypeScript 没有运行时。 这意味着,运行时中没有类型的表示。 类型只是 JS 本身存在的真实结构的别名。 换句话说,当你定义一个 TS 类型时,你需要告诉编译器这个类型在运行时所代表的确切结构。

这意味着如果我说某个类型A表示为{x: string} ,那么当我创建一个类型A的值时,我需要在其中放置一些 object 并且具有 x 属性作为字符串的东西。 TypeScript 永远不会自己创建这样的结构。 它需要从服务器响应中创建或给出。 所以这是运行时责任。

回到您的问题 - 问题是您正在定义您的函数具有__type属性形式的判别性,但您从未真正在其中任何一个中设置此属性。 所以你在愚弄类型系统,说 f 是 NumFunc 而 g 是 StrFunc,但这在运行时没有真正的表示。 Switch 在运行时工作,并且没有您使用的__type属性。

要解决此问题,您需要手动将 append 此属性设置为功能。 例如:

let myStrFunc = ((s: string) => `Hello, ${s}!`) as StrFunc;
myStrFunc.__type = 'StrFunc'


let myNumFunc = ((n: number) => `Hello x${n}!`) as NumFunc;
myNumFunc .__type = 'NumFunc'

现在这两个函数都需要判别式并且应该可以工作。 希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM