首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何提示我不控制的函数的类型?

如何提示我不控制的函数的类型?
EN

Stack Overflow用户
提问于 2021-08-07 09:46:40
回答 3查看 215关注 0票数 3

在解析JSON格式的字符串时,我得到一个linter错误:

代码语言:javascript
运行
复制
let mqttMessage = JSON.parse(message.toString())

// ESLint: Unsafe assignment of an `any` value. (@typescript-eslint/no-unsafe-assignment)

我控制着message的内容,所以我想告诉TS,JSON.parse()产生的实际上是一个对象。我怎么能这么做?

注:我可以沉默警告,但我想了解是否有更好的方法来处理这个问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-08-07 10:00:38

问题是JSON.parse返回一个any类型。

这是公平的- TypeScript不知道它是要解析出一个字符串、一个数字还是一个对象。

你有个叫‘不允许将变量赋值为的规则。

所以你可以强迫你的JSON.parse结果

代码语言:javascript
运行
复制
type SomeObjectIKnowAbout = {

}; 
const result = JSON.parse(message.toString()) as SomeObjectIKnowAbout; 

在这个场景中,我喜欢做的是创建一个特定的解析函数,它将在运行时断言obj确实是您所说的形状,并且在您将代码编写为该对象时可以对其进行类型转换。

代码语言:javascript
运行
复制
type SomeObjectIKnowAbout = {
    userId: string; 
}

type ToStringable = {
    toString: () => string; 
}

function parseMessage(message: ToStringable ) : SomeObjectIKnowAbout {
    const obj = JSON.parse(message.toString()); //I'm not sure why you are parsing after toStringing tbh. 

    if (typeof obj === 'object' && obj.userId && typeof obj.userId === 'string') {
        return obj as SomeObjectIKnowAbout; 
    }
    else {
        throw new Error ("message was not a valid SomeObjectIKnowAbout"); 
    }
}
票数 2
EN

Stack Overflow用户

发布于 2021-08-07 09:56:18

JSON.parse不是泛型的,所以我们不能提供一个泛型参数来完成它。

你有几个选择。

简单的是,由于JSON.parse返回any,所以只需定义要分配给它的类型:

代码语言:javascript
运行
复制
let mqttMessage: MQTTMessage = JSON.parse(message.toString());

(我使用MQTTMessage作为适当类型的替补。)

但是,这可能不足以为每个人提供足够的类型,因为它假设字符串定义了您期望它定义的内容。问题是,如果你在其他地方这样做,你就会重复这个假设。

相反,您可以定义一个函数:

代码语言:javascript
运行
复制
function parseMQTTMessageJSON(json: string): MQTTMessage {
    const x: object = JSON.parse(json);
    if (x && /*...appropriate checks for properties here...*/"someProp" in x) {
        return x as MQTTMessage;
    }
    throw new Error(`Incorrect JSON for 'MQTTMessage' type`);
}

那么您的代码是:

代码语言:javascript
运行
复制
let mqttMessage = parseMQTTMessageJSON(message.toString());
票数 2
EN

Stack Overflow用户

发布于 2021-08-08 01:46:08

作为类型断言和运行时包装函数的替代方法,您可以利用声明合并parse方法添加一个泛型重载的全局JSON对象。这将允许您通过预期的类型,并为您提供改进的IntelliSense,以防您在解析时使用reviver

代码语言:javascript
运行
复制
interface JSON {
    parse<T = unknown>(text: string, reviver?: (this: any, key: keyof T & string, value: T[keyof T]) => unknown): T
}

type Test = { a: 1, b: "", c: false };

const { a, b, c } = JSON.parse<Test>(
    "{\"a\":1,\"b\":\"\",\"c\":false}",  
    //k is "a"|"b"|"c", v is false | "" | 1
    (k,v) => v
);

或者,如果您依赖声明文件来扩展全局接口:

代码语言:javascript
运行
复制
declare global {
  interface JSON {
    parse<T = unknown>(text: string, reviver?: (this: any, key: keyof T & string, 
  value: T[keyof T]) => unknown): T
  }
}

游乐场

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68691208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档