[英]Writing a getter of generic union type
From a union of two generic types I want to return the left value (or a default value if the union has the right type). 从两个通用类型的联合中,我想返回左值(如果联合具有正确的类型,则返回默认值)。 I tried but generics and
typeof
/ instanceof
seems to not work so great together. 我尝试过,但泛型和
typeof
/ instanceof
似乎不能很好地协同工作。
This is how I would write it in Haskell: 这就是我在Haskell中写的方式:
data Either a b = Left a | Right b
getLeftOrDefault :: a -> Either a b -> a
getLeftOrDefault _ (Left a) = a
getLeftOrDefault a (Right b) = a
and how would this translate to Typescript? 以及如何将其转换为Typescript? This was my try:
这是我的尝试:
function getLeftOrDefault<A, B>(either: A | B, backup: A) {
if (either instanceof A) {
return either;
}
return backup;
}
But this does not work. 但这是行不通的。 Any other way or workaround?
还有其他方法或解决方法吗?
TypeScript types exist only at compile-time (since Javascript has no notion of types). TypeScript类型仅在编译时存在(因为Javascript没有类型概念)。
Therefore, you can't use type parameters at runtime. 因此,您不能在运行时使用类型参数。
Instead, you can check if (either instanceof backup.constructor)
, which is an easy way to get the A
constructor at runtime. 相反,您可以检查
if (either instanceof backup.constructor)
,这是在运行时获取A
构造函数的简便方法。
Note that this will not work for primitives. 请注意,这不适用于原语。
As https://stackoverflow.com/a/51329983/6656422 states there are no TypeScript types at run time. 如https://stackoverflow.com/a/51329983/6656422所述,运行时没有TypeScript类型。 You have to test the "type".
您必须测试“类型”。 To make something generic you could pass in a tester.
要使通用的东西可以通过测试器。
function getLeftOrDefault<A, B>(either: A | B, backup: A, isA: (obj: any) => obj is A): A {
if (isA(either)) {
return either;
}
return backup;
}
Usage: 用法:
Many times interfaces are used for strongly typing object literals, you can test the property(ies). 很多时候,接口都用于强类型化对象文字,您可以测试属性。
interface Car {
engine: string;
}
interface Tree {
branches: any[];
}
function isCar(obj: any): obj is Car {
return !!obj.engine;
}
const myCar: Car = { engine: '350' };
const myTree: Tree = { branches: [] };
const myBackup: Car = { engine: '396' };
getLeftOrDefault(myCar, myBackup, isCar); // -> { engine: '350' }
getLeftOrDefault(myTree, myBackup, isCar); // -> { engine: '396' }
If your types are classes they have constructors at run time. 如果您的类型是类,则它们在运行时具有构造函数。
class Car {
constructor(public engine: string) {}
}
class Tree {
constructor(public branches: any[]) {}
}
function isCar(obj: any): obj is Car {
return obj instanceof Car;
}
const myCar: Car = new Car('350');
const myTree: Tree = new Tree([]);
const myBackup: Car = new Car('396');
getLeftOrDefault(myCar, myBackup, isCar); // -> { engine: '350' }
getLeftOrDefault(myTree, myBackup, isCar); // -> { engine: '396' }
However constructor checking is not fool proof because of casting 但是,由于强制转换,构造函数检查不是万无一失的
const myCar: Car = { engine: '350' };
const myTree: Tree = { branches: [] };
const myBackup: Car = { engine: '396' };
getLeftOrDefault(myCar, myBackup, isCar); // -> { engine: '396' }
getLeftOrDefault(myTree, myBackup, isCar); // -> { engine: '396' }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.