有没有办法对一个对象的"instanceof"式查询对照语言中内置的联合类型?
我有一个带有union类型的类型别名,如下所示:
type MyType = Foo | Bar | Thing;
Run Code Online (Sandbox Code Playgroud)
每一个Foo,Bar并Thing继承自Base
class Base { /* ... */ }
class Foo extends Base { /* ... */ }
class Bar extends Base { /* ... */ }
class Thing extends Base { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
一些方法返回一个Base.
function getBase(): Base { /* ... */ return base; }
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想创建另一个可以返回MyType后调用的方法getBase()
function getMyType(): MyType {
var item = getBase();
if (item instanceof MyType)
return item;
else
return null;
}
Run Code Online (Sandbox Code Playgroud)
如果MyType不是类型别名,则上述代码将起作用.但是,由于它是一个类型别名,它似乎不起作用.因此,为了重新思考我的问题,这种语言内置了什么?
显然,我想要的是通过针对每个单独的类检查instanceof查询来完成:
function getMyType(): MyType {
var item = getBase();
if (item instanceof Foo || item instanceof Bar || item instanceof Thing)
return item;
else
return null;
}
Run Code Online (Sandbox Code Playgroud)
但这并不理想; 如果一些未来的开发人员想要创建OtherThing和扩展MyType以包含这个新类,那么希望记得更新getMyType().
语言中是否有内置功能来解决这个问题,或者是否有更好的方法可以做到这一点?
Exp*_*ter 60
如果您知道感兴趣的类型的某些特定键,您可以通过运算符来完成in:
function move(pet: Fish | Bird) {
if ("swim" in pet) {
return pet.swim(); //pet is Fish
}
return pet.fly(); //pet is Bird
}
Run Code Online (Sandbox Code Playgroud)
对我来说比附加功能要容易得多。这就是我一直在寻找的。
jts*_*ven 11
自已接受的答案发布以来,Typescript 引入了一些新功能,使这一切变得更容易。从 Typescript 3.8.3 开始,我将在 2020 年执行此操作:
const myTypes = ['Foo', 'Bar', 'Thing'] as const;
type MyType = typeof myType[number]; // 'Foo' | 'Bar' | 'Thing'
// Return a typed MyType if string is valid (else throw).
function getMyType(maybeMyType: string): MyType {
const myType = myTypes.find((validType) => validType === maybeMyType);
if (myType) {
return myType;
}
throw new Error(`String "${maybeMyType}" is not of type MyType.`);
}
// Use it like this:
const definitelyMyType = getMyType('Foo');
Run Code Online (Sandbox Code Playgroud)
或者,如果您更喜欢不太安全但可以说更易读的自定义类型保护样式,您可以这样做:
// Define a custom type guard to validate & assert that maybeMyType is MyType.
function isMyType(maybeMyType: string): maybeMyType is MyType {
return myTypes.includes(maybeMyType);
}
// Use it like this:
const maybeMyType = 'Foo';
if (isMyType(maybeMyType)) {
const definitelyMyType: MyType = maybeMyType;
}
Run Code Online (Sandbox Code Playgroud)
没有类型别名的运行时表示,因此本身没有任何“内置”来进行这种检查。
不过,这种模式相当容易维护:
// Future devs: Please keep these in sync
type MyType = Foo|Bar|Thing;
let MyTypeClasses = [Foo,Bar,Thing];
function getMyType(): MyType {
var item = getBase();
if (MyTypeClasses.some(c => item instanceof c))
return item;
else
return null;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1709 次 |
| 最近记录: |