Typescript 验证typeguard中的多个类型
是否可以在一个类型保护中验证多个类型?这就是我想要的:Typescript 验证typeguard中的多个类型,typescript,Typescript,是否可以在一个类型保护中验证多个类型?这就是我想要的: interface A { } interface B extends A { foo: number; } interface C extends A { bar: number; } function is<T extends A>(item: A): item is T { if((item as B).foo) // validate as B if((item as A).bar)
interface A { }
interface B extends A {
foo: number;
}
interface C extends A {
bar: number;
}
function is<T extends A>(item: A): item is T {
if((item as B).foo)
// validate as B
if((item as A).bar)
// validate as A
}
接口A{}
接口B扩展了A{
foo:数字;
}
接口C扩展了{
条:数字;
}
功能为(项目:A):项目为T{
如果((项目为B.foo)
//验证为B
如果((项目为.bar)
//验证为
}
我打算这样使用它:
if(is<B>(item)) {
// do stuff
}
如果(是(项目)){
//做事
}
如上所述,你想要的是不可能的
静态类型系统是在编译TypeScript代码时使用的。所以这个类型脚本代码:
const item: A = { foo: 123 };
if (is<B>(item)) { console.log(item.foo.toFixed(2)); }
if (is<C>(item)) { console.log(item.bar.toFixed(2)); }
const item: A = Math.random() < 0.5 ? { foo: 123 } : { bar: 456 };
if (is(item)) { console.log(item.foo.toFixed(2)); }
if (is(item)) { console.log(item.bar.toFixed(2)); }
现在至少可以想象,is()
的实现可以使用第二个参数来确定应该检查哪个属性。事实证明,实现并给出适当的强类型签名是可能的,尽管看到魔术背后的精巧装置可能会令人失望:
type PossibleTypes = B | C;
const props = {
B: "foo",
C: "bar"
} as const
type Props = typeof props;
function is<K extends keyof Props>(
item: A,
typeName: K
): item is Extract<PossibleTypes, Record<Props[K], number>> {
const key = props[typeName];
return ((key in item) && (typeof (item as any)[key] === "number"));
}
但我想这取决于你的用例和气质
哇,谢谢你的详细回答,非常感谢
type PossibleTypes = B | C;
const props = {
B: "foo",
C: "bar"
} as const
type Props = typeof props;
function is<K extends keyof Props>(
item: A,
typeName: K
): item is Extract<PossibleTypes, Record<Props[K], number>> {
const key = props[typeName];
return ((key in item) && (typeof (item as any)[key] === "number"));
}
function isB(item: A): item is B {
return ("foo" in item) && (typeof (item as any).foo === "number");
}
function isC(item: A): item is C {
return ("bar" in item) && (typeof (item as any).bar === "number");
}
const item: A = Math.random() < 0.5 ? { foo: 123 } : { bar: 456 };
if (isB(item)) { console.log(item.foo.toFixed(2)); }
if (isC(item)) { console.log(item.bar.toFixed(2)); }