[英]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.