Typescript控制流分析不支持';我认不出一种已知的类型
我试图理解为什么需要明确告诉编译器Typescript控制流分析不支持';我认不出一种已知的类型,typescript,Typescript,我试图理解为什么需要明确告诉编译器策略类型中的值的类型是什么,即使它只能是我的类型之一 type Types = 'baz' | 'bar'; // tagged union types type Foo<T extends Types> = { type: T; } type FooOne = { one: string } & Foo<'baz'>; type FooAnother = { another: string } & Foo<'ba
策略
类型中的值的类型是什么,即使它只能是我的类型之一
type Types = 'baz' | 'bar';
// tagged union types
type Foo<T extends Types> = { type: T; }
type FooOne = { one: string } & Foo<'baz'>;
type FooAnother = { another: string } & Foo<'bar'>;
type Predicate<T extends Types> = (e: Foo<T>) => boolean;
type Policies = {
[P in Types]: Predicate<P>
}
const policies: Policies = {
baz: (e: FooOne) => e.one === 'neo',
bar: (e: FooAnother) => e.another === 'morphieus'
}
// this method receives a union type
function verify(e: FooOne | FooAnother) {
// these both work, understandably
if (e.type === 'baz') {
const policy1 = policies[e.type]; // ide says this type is a Predicate<'baz'>
const result1 = policy1(e); // fine
} else {
const policy2 = policies[e.type]; // and this is a Predicate<'bar'>
const result2 = policy2(e); // fine
}
// but this doesn't work even though e.type is known to be 'baz' | 'bar', and the keys at policies can only be 'baz' | 'bar'
const policy3 = policies[e.type]; // ide says this type is a Predicate<'bar'> | Predicate<'baz'>
const result3 = policy3(e); // error Cannot invoke an expression whose type lacks a call signature
// this works, if i hint to the compiler what is at policies[T]
const policy4: Predicate<Types> = policies[e.type]; // Predicate<'baz' | bar'>
const result4 = policy4(e); // fine
}
type类型='baz'|'bar';
//标记的联合类型
类型Foo={type:T;}
输入FooOne={one:string}&Foo;
键入footheran={otheran:string}&Foo;
类型谓词=(e:Foo)=>boolean;
类型策略={
[P在类型中]:谓词
}
常量策略:策略={
baz:(e:FooOne)=>e.one==='neo',
酒吧:(e:footheran)=>e.otheran=='morphieus'
}
//此方法接收联合类型
功能验证(e:FooOne | foooother){
//可以理解,这两种方法都有效
如果(e.type=='baz'){
const policy1=policies[e.type];//ide说此类型是谓词
const result1=policy1(e);//很好
}否则{
const policy2=policies[e.type];//这是一个谓词
const result2=policy2(e);//很好
}
//但即使e.type被称为“baz”|“bar”,并且策略的键只能是“baz”|“bar”,这也不起作用
const policy3=policies[e.type];//ide说此类型是谓词|谓词
const result3=policy3(e);//错误无法调用其类型缺少调用签名的表达式
//如果我向编译器提示策略[T]中的内容,这是可行的
const policy4:Predicate=policies[e.type];//Predicate这里没有好的解决方案,您需要某种类型的断言才能使事情正常进行
问题在于,流分析无法跟踪值的来源。因此,当您编写时:
const policy3 = policies[e.type];
const result3 = policy3(e);
policy3
将是Predicate | Predicate
,但编译器不知道是哪一个。当调用policy3
时,由于它不知道变量中实际包含的函数类型,因此在较新版本中,它将强制您指定一个参数,该参数可以与联合中的任一函数一起使用。它不记得在policy3
si实际上与e绑定。type
和policy3(e)
将是类型安全的。(仅供参考:在较旧版本中,policy3
将根本不可调用,因为它是一个联合)
此代码适用于:
const policy4= policies[e.type] as Predicate<Types> ; // Predicate<'baz' | bar'>
const result4 = policy4(e); // fine
const policy4=策略[e.type]as Predicate;//predicateEyeah,至少现在是这样。我认为不会处理这些类型的相关类型。我已经尝试过了,但可能不会实现。现在我想说,只要断言你的方法就可以了。谢谢你的详细回答。我想我不介意告诉编译器它是否不够聪明我知道。但是我更担心的是我所做的事情有一些不安全的地方。我真的看不到任何会导致事情突然爆炸的案例runtime@AaronHS就像jcalz评论的那样,他们可以实现这一点,但他们只是没有(我不是在责怪他们,而是优先级…)这是安全的。