如何从Map <string,object =“”>方法返回强类型值

时间:2019-02-12 19:23:59

标签: typescript

我从事C#工作已经有一段时间了,最​​近开始使用TypeScript V3.1.6从事Node.js项目的工作。我很高兴Typescript现在支持泛型,这是我期望随着C#的过渡而失去的一件事。

我的C#代码是DataRow包装器,允许我使用泛型从Dictionary中提取强类型值,如下所示:

Dictionary<string, object> Values = new Dictionary<string, object>();
public T Parse<T>(string columnName)
{
    T result = default(T);
    result = (T)Convert.ChangeType(this.Values[columnName], typeof(T));
    return result;
}

我当前的TypeScript代码如下:

export class DataRow {
    private Values: Map<string, object> = new Map<string, object>();
    constructor(row?: any) {
        if (!!row) {
            for (let key in row) {
                this.Values.set(key, row[key]);
            }
        }
    }

    public Value<T>(key: string): T {
         //Not exactly how to replicate the return.
    }
}

我的C#代码行:

T result = default(T);

如果该值为null,则允许我返回该类型的默认值。为了简洁起见,我从C#示例中删除了其他一些null检查和字典检查。我的主要想法/问题是:

1)您可以在Typescript中获得通用类型的默认类型吗?

2)由于我是TypeScript的新手,请随时指出我的TypeScript代码到目前为止存在的明显问题。

3)返回强类型值是否会影响Node.js的性能?

更新:

我已经将课程更新为:

export class DataRow {

    private Values = new Map<string, any>();

    constructor(row?: any) {
        if (!!row) {
            for (let key in row) {
                this.Values.set(key, row[key]);
            }
        }
    }

    public Value<T>(key: string): T {
        if (this.Values.has(key)) {
            let value = this.Values.get(key);

            if (!!value) {
                return value as T;
            }
        }
        return <unknown>null as T;
    }
}

现在效果很好。感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

TypeScript为您提供仅在构建时进行静态键入的好处。您的代码将被编译为JavaScript,然后您的应用程序才能在NodeJS环境中执行,因此您不必担心会返回任何强类型的内容或性能,因为您的应用程序中根本没有TS。运行时。

关于默认值的问题,您只需检查地图中该值的存在,如果没有值就返回默认值。

public Value<T>(key: string): T {
  if (this.Values.has(key) {
    return this.Values.get(key)
  } else {
    // return some kind of default.
  }
}

关于可能的改进,我建议您将您的类变成泛型以提高类型安全性。

// Class is now a generic with a default type of `object`.
export class DataRow<T = object> {
    // You don't need to explicitly type the Values. TS can infer that.
    private Values = new Map<string, T>();

    // Explicitly type the row argument for type safety.
    constructor(row?: { [key: string]: T }) {
        // In JS/TS land you don't have to explicitly cast
        // values to booleans to be able to make a truth check.
        if (row) {
            for (let key in row) {
                this.Values.set(key, row[key]);
            }
        }
    }

    public Value(key: string): T {
        if (this.Values.has(key)) {
             return this.Values.get(key)
        } else {
             // return some kind of a default
         }
    }
}