我可以创建一个 TypeScript 类型并在 AJAX 返回 JSON 数据时使用它吗?

Posted

技术标签:

【中文标题】我可以创建一个 TypeScript 类型并在 AJAX 返回 JSON 数据时使用它吗?【英文标题】:Can I create a TypeScript type and use that when AJAX returns JSON data? 【发布时间】:2012-10-30 12:15:05 【问题描述】:

我有以下 C# 类:

public class JsonBackup

    public int Added  set; get; 
    public int DEVCount  set; get; 
    public int DS1Count  set; get; 
    public IList<ViewEvent> Events  get; set; 
    public IEnumerable<string> Errors  set; get; 
    public int Rejected  set; get; 
    public bool Success  set; get; 
    public int Updated  set; get; 

这段代码将 JSON 数据返回到我的浏览器:

return Json(new JsonBackup

    Added = added,
    DEVCount = devCount,
    DS1Count = ds1Count,
    Events = t.Events,
    Rejected = rejected,
    Success = true,
    Updated = updated
);

这里返回数据:

 $.ajax("/Backup/Data/Backup",
    
        cache: false,
        dataType: 'json',
        type: 'POST'
    )
 .done(function (data: ) 
     console.log(data);
     backupDone(data, ajaxElapsed);
 );

并用于其他地方和这里:

   $.each(data.Events, function (i, item) 
        $("#stats-list li:eq("+(4+i)+")").after('<li>' + item.Description + ' : ' + item.Elapsed + ' ms</li>');
    );

我是否可以创建一个 TypeScript 类型并将数据分配给该类型,以便我可以 例如,在选择诸如

之类的东西时获得智能感知
data.Added or data.DEVCount etc?

【问题讨论】:

【参考方案1】:

实现这一目标的最简单方法是为 IJsonBackup 创建接口,当您收到 json 时,只需将其转换为 IJsonBackup

interface IViewEvent



interface IJsonBackup

    Added : number;
    DEVCount : number;
    DS1Count : number;
    Events : IViewEvent[];
    Errors : string[];
    Rejected : number;
    Success : bool;
    Updated : number;

在你的类定义中:

backupDone(data: IJsonBackup, ajaxElapsed: any)



$.ajax("/Backup/Data/Backup",
    
        cache: false,
        dataType: 'json',
        type: 'POST'
    )
    .done(function (data: any) 
        console.log(data);
        backupDone(<IJsonBackup>data, ajaxElapsed);
    );

【讨论】:

我预计这里会有一个巨大的问题。如果服务器以字符串的形式发送数字怎么办?如果我们不显式调用parseFloat,那么我们会得到字符串而不是数字。如果它们彼此相加,它们最终将连接起来,而不是像 30+42=3042。想象一下,您试图计算一个平均值,但它们被错误地添加了。编译时类型检查只会使情况变得更糟,因为您确定它们是数字但它们不是。这将导致难以跟踪的错误。 是的,这可能是个问题,我同意。在这种情况下,IMO 在我们将数据进一步向下传递之前,我们负责所有需要的解析,并且只有在完成之后,我们才能安全地引入接口类型安全性。 Typescript 不会自己解决这个问题,它不是解决这个问题的正确工具:)。这也是一个更通用的应用程序,它并不是真正仅与 TS 相关 - 如果数据以不同的表示形式到达,我们应该始终将数据解析为预期的格式。 大多数具有静态类型的语言可以保证函数参数确实是选择的那些确切类型。 Typescript 不保证 100%。之所以会这样,是因为 ts 类型是可选的,它必须与无类型的 js 代码兼容。 当然,但是在任何语言中,如果您从“外部”接收到一些数据(例如从服务器响应 json),您必须直接或间接解析它以确保正确的类型。 在这种情况下您不会收到Conversion of type 'AxiosResponse&lt;any&gt;' to type 'IAbout' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. 错误吗?

以上是关于我可以创建一个 TypeScript 类型并在 AJAX 返回 JSON 数据时使用它吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中进行运行时类型转换?

TypeScript 中每个键的泛型映射对象类型

Typescript:使用装饰器时的类型推断

TypeScript-泛型

如何在 TypeScript 中创建自定义类型

使用TypeScript中的TypeScript库