以通用方式解析简单值类型

时间:2019-07-05 12:44:14

标签: node.js typescript

我想解析值,例如使用TypeScript以通用方式从process.env中获取:

type SimpleType = string | number | boolean

function getEnv<T extends SimpleType>(name: string): T { 
  return process.env[name] as T
}

但是TypeScript中的as关键字不提供类型转换(例如在C#中)。

有通用的方法吗?

3 个答案:

答案 0 :(得分:2)

Titian's answer很棒,但是我会采取稍微不同的方法。

由于他已经确定类型与运行时无关,所以我们确实需要以值的形式传递类型信息,但是在这种情况下并不一定需要switch

StringNumberBoolean的构造函数都可以被静态调用以将任何值转换为它们各自的基元,因此我们可以定义一个函数,其中提供了一个静态函数,如下所示:第二个参数。

type SimpleType = string | number | boolean;

interface SimpleConstructor<T extends SimpleType> {
  (value: any): T;
}

function getEnv<T extends SimpleType>(name: string, cast: SimpleConstructor<T>): T { 
  return cast(process.env[name]);
}

const foo = getEnv('foo', String);
const bar = getEnv('bar', Number);

在这里,foo被推断为类型string,而bar被推断为类型number

答案 1 :(得分:1)

类型断言(as关键字)仅告诉编译器您知道比编译器更好的类型,它们不提供运行时功能。 此外,类型会在编译时删除,因此您无法在运行时根据T传递给函数的内容来做出决定

一种方法是传递一个string来表示您想要的转换,并切换一个开关来执行相应的转换。 Typescript可以帮助您根据传入的字符串正确键入返回类型:

type SimpleTypeNames = "string" | "number" | "boolean"
type SimpleTypeNamesToType<T extends SimpleTypeNames> =  
    T extends "string" ? string :
    T extends "number" ? number :
    T extends "boolean" ? boolean :
    never

function getEnv<T extends SimpleTypeNames>(name: string, type: T): SimpleTypeNamesToType<T>
function getEnv(name: string, type: SimpleTypeNames): SimpleTypeNamesToType<SimpleTypeNames> 
{ 
    switch(type) {
        case "boolean" : return !!process.env[name];
        case "number" : return +process.env[name];
        case "string" : return process.env[name] + "";
    }
}

getEnv("b", "boolean") // return boolean

答案 2 :(得分:0)

as不提供类型转换。实际上,as将在已编译的JS中被剥离。唯一的用途是在编写代码时澄清类型,基本上是在开发人员比TS的自动类型检查更了解类型的情况下,例如:

const foo = Math.random()<5 ? {bar:'42'} : {bar:42};
// TS thinks that 'foo: {bar: string} | {bar: number}'
// But the developer knows that 'foo: {bar: string}'
// 'as' can be used to prevent TS from throwing error when we know they won't happen:
const someString: string = foo.bar; // error
const someOtherString: string = (foo.bar as string); // no error

JS中没有实际的类型转换,因为在运行时没有类型-类型仅在编译时存在于“ TS层”中。从另一种类型创建某种类型的对象的JS方法是factory functions