Node.js 以通用方式解析简单值类型
我想使用TypeScript以通用方式解析值,例如来自Node.js 以通用方式解析简单值类型,node.js,typescript,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 } type SimpleType=string | number | boolean 函数getEnv(名称:string):T{ 将
process.env
:
type SimpleType = string | number | boolean
function getEnv<T extends SimpleType>(name: string): T {
return process.env[name] as T
}
type SimpleType=string | number | boolean
函数getEnv(名称:string):T{
将process.env[name]返回为T
}
但是TypeScript中的as
关键字不提供类型转换(例如在C#中)
有没有一种通用的方法可以做到这一点?
,因为
不提供类型转换。事实上,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
const foo=Math.random()类型断言(作为
关键字的as)只需告诉编译器您比编译器更了解某事物的类型,它们不提供运行时功能。
此外,类型在编译时被擦除,因此您无法在运行时根据传递给函数的t
做出决定
一种方法是传入一个表示所需转换的a字符串,并使用一个开关来执行相应的转换。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
键入SimpleTypeNames=“string”|“number”|“boolean”
类型SimpleType PenameType=
T扩展“字符串”?字符串:
T扩展“数字”?编号:
T扩展了“布尔”?布尔值:
从未
函数getEnv(名称:string,类型:T):SimpleTypeNamesToType
函数getEnv(名称:string,类型:SimpleTypeNames):SimpleTypeNamesToType
{
开关(类型){
大小写“boolean”:return!!process.env[name];
案例“编号”:return+process.env[名称];
大小写“string”:返回进程.env[name]+“”;
}
}
getEnv(“b”,“boolean”)//返回boolean
很好,但我会采取稍微不同的方法
因为他已经确定类型对运行时没有影响,所以我们确实需要以值的形式传递类型信息,但在这种情况下不一定需要开关
和构造函数都可以被静态调用,以便将任何值转换为它们各自的原语,因此我们可以定义一个函数,其中提供一个静态函数作为第二个参数
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);
type SimpleType=string | number | boolean;
接口SimpleConstructor{
(值:任意):T;
}
函数getEnv(名称:string,强制转换:SimpleConstructor):T{
返回cast(process.env[name]);
}
常量foo=getEnv('foo',字符串);
常数条=getEnv('条',编号);
这里,foo
被推断为类型string
,而bar
被推断为类型number运行时不受类型的影响。因此,getEnv('foo')
无法在运行时执行与getEnv('foo')
不同的代码。另一方面,您当前的代码:它不会抛出任何TS错误。很酷,这正是我试图构建的,但是cast:SimpleConstructor
让我大吃一惊。是的,我刚才注意到的更好,不管字符串
值是什么(process.env.*始终是一个字符串
)我传入getEnv('foo',Boolean)
,它总是返回true
@AlexanderZeitler,它唯一会为false的字符串值是“
,例如空字符串。这就是字符串的真实性的工作原理。如果您想解释某些字符串值,如“false”
、“0”
,等等,您将不会有如此优雅的解决方案——您需要布尔值(JSON.parse(process.env.*)
,而不仅仅是布尔值(process.env.*)
。