Generics 获取泛型参数的类型

Generics 获取泛型参数的类型,generics,types,typescript,Generics,Types,Typescript,为了更好地处理类型,我编写了小函数 function evaluate(variable: any, type: string): any { switch (type) { case 'string': return String(variable); case 'number': return isNumber(variable) ? Number(variable) : -1; case 'boolean': {

为了更好地处理类型,我编写了小函数

function evaluate(variable: any, type: string): any {
    switch (type)
    {
        case 'string': return String(variable);
        case 'number': return isNumber(variable) ? Number(variable) : -1;
        case 'boolean': {
            if (typeof variable === 'boolean')
                return variable;

            if (typeof variable === 'string')
                return (<string>variable).toLowerCase() === 'true';

            if (typeof variable === 'number')
                return variable !== 0;

            return false;
        }
        default: return null;
    }
}

function isNumber(n: any): boolean {
    return !isNaN(parseFloat(n)) && isFinite(n);
}
函数求值(变量:any,类型:string):any{
开关(类型)
{
大小写“string”:返回字符串(变量);
案例“编号”:返回isNumber(变量)?编号(变量):-1;
“布尔”大小写:{
如果(变量类型==='boolean')
返回变量;
如果(变量类型==='string')
return(变量).toLowerCase()='true';
如果(变量类型==='number')
返回变量!==0;
返回false;
}
默认值:返回null;
}
}
函数isNumber(n:any):布尔值{
return!isNaN(parseFloat(n))和&isFinite(n);
}

我也尝试过泛型,但不知道如何从泛型参数中获取类型。有可能吗?

typeof
是一个JavaScript操作符。它可以在运行时用于获取JavaScript知道的类型。泛型是一种类型脚本概念,它有助于检查代码的正确性,但在编译输出中不存在。所以简单的回答是不,这是不可能的

但你可以这样做:

class Holder<T> {
    value: T;
    constructor(value: T) {
        this.value = value;
    }
    typeof(): string {
        return typeof this.value;       
    }
}
类持有者{
值:T;
构造函数(值:T){
这个值=值;
}
typeof():字符串{
返回此.value的类型;
}
}


这是因为我操作的是Holder内部的值,而不是Holder本身。

您无法消除
类型
字符串,但您可以通过添加重载使函数在类型方面更加智能和可用:

function evaluate(variable: any, type: 'string'): string;
function evaluate(variable: any, type: 'number'): number;
function evaluate(variable: any, type: 'boolean'): boolean;
function evaluate(variable: any, type: string): unknown {
    ...
    default: throw Error('unknown type');
}

请注意,不再有空的情况,因为不可能知道未知的
字符串
类型在编译时是否实际包含有效值,如
'number'

这对大多数人来说已经足够了


然而

请注意,mysteryType联合不起作用。如果出于某种原因确实希望它起作用,可以改用条件类型:

function evaluate<T extends string>(variable: any, type: T):
    T extends 'string' ? string :
    T extends 'number' ? number :
    T extends 'boolean' ? boolean :
    never;
function evaluate(variable: any, type: string): unknown {
    ...
    default: throw Error('unknown type');
}


另外,如果您在谷歌上搜索这个问题,并且想知道如何从
MyClass
获取
T
,也可以这样做:
类MyClass{}

键入GetMyClassTNot它不是。TypeScript的键入只是编译时功能。输出JavaScript没有类型信息,也没有反射功能。您必须像在JavaScript中一样依赖代码中良好的
typeof
!!可变的
@PeterWone更改行为,当前只有
“true”
(不区分大小写)会导致true,但是
!!变量
将导致所有非空字符串为true。你可以申请!!如果需要,返回两个非字符串分支。返回此.value.constructor['name'];//理论上你也可以这样做:函数create(c:{new():T;}):T{return new c();}如果我通过我自己的对象,比如Car,它将警告“Object”,那么它就不能工作;而不是“汽车”
function evaluate<T extends string>(variable: any, type: T):
    T extends 'string' ? string :
    T extends 'number' ? number :
    T extends 'boolean' ? boolean :
    never;
function evaluate(variable: any, type: string): unknown {
    ...
    default: throw Error('unknown type');
}
const mysteryType = 'number' as 'boolean' | 'number';
const myMystery = evaluate('91823', mysteryType); // myMystery: number | boolean
class MyClass<T> {}

type GetMyClassT<C extends MyClass<any>> = C extends MyClass<infer T> ? T : unknown;
const myInstance = new MyClass<"hello">();
let x: GetMyClassT<typeof myInstance>; // x: "hello"