打字稿不会缩小函数构造函数

     2023-02-18     205

关键词:

【中文标题】打字稿不会缩小函数构造函数【英文标题】:Typescript doesn't narrow on function constructor 【发布时间】:2022-01-15 17:24:25 【问题描述】:

我正在使用一个名为 DNSHandler 的构造函数,其接口如下所示:

interface DNSHandler 
    received: Partial<DNSStandardQuery>;
    ParseDNSStandardQuery(): boolean;
    __parseDomain(domainBuf: Buffer): string;

其中 DNSStandardQuery 的接口包含许多我想在调用 DNSHandler 的ParseDNSStandardQuery() 时填写的属性。

所以在 DNSStandardQuery 的构造函数中,我将 this.received 初始化为一个空对象,并用 DNSBuffer: Buffer 填充它的第一个属性 - rawQuery

this.received = ;
this.received.rawQuery = DNSBuffer;

但是当我在ParseDNSStadndardQuery() 方法中引用this.received.rawQuery 时:

this.ParseDNSStadndardQuery = function() 
    if (this.received.rawQuery.length < 21) ...

我明白了:

Object is possibly 'undefined'. TS(2532)

我知道我明白了,因为 this.received 被声明为 Partial 类型,但我预计它会在构造函数部分中缩小。

我错过了什么?

下面的整个(最小)示例,因为遇到每个 buff = this.received.rawQuery 引用 Object is possibly 'undefined'.ts(2532) 错误:

const DOT_ASCII = 46;


interface DNSStandardQuery
    rawQuery: Buffer;
    transactiodID: number;
    flags: number;
    questions: number;
    type: number;
    class: number;
    domain: string;


interface DNSHandler
    received: Partial<DNSStandardQuery>;
    ParseDNSStadndardQuery(): void;
    __parseDomain(domainBuf: Buffer): string;


const DNSHandler = function(this: DNSHandler, DNSBuffer: Buffer)
    this.received = ;
    this.received.rawQuery = DNSBuffer;
    // Only handles standard queries with single question, with  type 'A' internet class queries.
    this.ParseDNSStadndardQuery = function()
        let received = this.received;
        let buff = this.received.rawQuery;
        if (this.received.rawQuery.length < 21) console.error("Got too short message"); return false;
        received.transactiodID = parseShort(buff[0], buff[1]);
        received.flags = parseShort(buff[2], buff[3]);
        received.questions = parseShort(buff[4], buff[5]);
        received.class = parseShort(buff[buff.length - 2], buff[buff.length - 1])
        received.type = parseShort(buff[buff.length - 4], buff[buff.length - 3])
        received.domain = this.__parseDomain(buff.slice(12, buff.length-4));
    

    this.__parseDomain = function(domainBuf: Buffer)
        let domain = [];
        let bytesToRead = domainBuf[0];
        while(bytesToRead)
            domain.push(...domainBuf.slice(1, bytesToRead+1) as unknown as number[],DOT_ASCII);
            domainBuf = domainBuf.slice(bytesToRead+1);
            bytesToRead = domainBuf[0];
        
        // Remove trailed DOT
        return String.fromCharCode(...domain.slice(0, domain.length-1));
    
 as any as new(DNSBuffer: Buffer): DNSHandler

【问题讨论】:

你给我们的代码太少了,你的解释太模糊了,没有填补空白。为什么不在问题末尾发布所有代码?您真正应该做的是提供minimal reproducible example。通过创建minimal reproducible example,您可以将问题缩小到本质,我自己解决问题! received: Partial&lt;DNSStandardQuery&gt; 表示received 可能是一个空对象。您可能在某个时候设置了它,但 TS 无法真正可靠地知道您提到的函数何时被称为您要使用的属性已被定义 @Inigo 已更新。感谢您的反馈,这是我的第一个问题 :) @apokryfos 那么在这种情况下建议做什么呢? 【参考方案1】:

好的,经过一些尝试为这种情况找到最佳解决方案后,我找到了一个有希望的解决方案

而不是像我以前那样将属性声明为部分属性:

interface DNSHandler
    received: Partial<DNSStandardQuery>;
    ParseDNSStadndardQuery(): boolean;
    __parseDomain(domainBuf: Buffer): string;

你可以用通常的方式声明属性:

interface DNSHandler
    received: Partial<DNSStandardQuery>;
    ParseDNSStadndardQuery(): boolean;
    __parseDomain(domainBuf: Buffer): string;

然后用 语法初始化对象:

const DNSHandler = function(this: DNSHandler, DNSBuffer: Buffer)
    this.received = <DNSStandardQuery>;
...

【讨论】:

使用打字稿在构造函数中动态设置类属性

】使用打字稿在构造函数中动态设置类属性【英文标题】:Usetypescripttodynamicallysetclasspropertyinconstructor【发布时间】:2021-12-3105:36:31【问题描述】:我正在尝试创建一个打字稿类MyClass,并在构造函数中动态设置实例属性:constmyIns... 查看详情

类装饰器上的打字稿文档-返回“类扩展构造函数”的函数

】类装饰器上的打字稿文档-返回“类扩展构造函数”的函数【英文标题】:TypescriptDocumentationonClassDecorator-functionreturning"classextendsconstructor"类装饰器上的打字稿文档-返回“类扩展构造函数”的函数【发布时间】:2019-10-060... 查看详情

打字稿接口和承诺返回一个对象/构造函数?

】打字稿接口和承诺返回一个对象/构造函数?【英文标题】:Typescriptinterfacesandpromisereturnanobject/constructor?【发布时间】:2022-01-1407:10:09【问题描述】:我有一个返回类型的Promiseperson.tsconstpersonFactory:PersonFactory=(name,lastName)=>(spea... 查看详情

何时在 Angular2 打字稿中创建构造函数?

】何时在Angular2打字稿中创建构造函数?【英文标题】:WhentocreateconstructorinAngular2typescript?【发布时间】:2016-09-1414:26:05【问题描述】:以下是来自Angular2docs的一些示例构造函数:exportclassAppComponentimplementsOnInittitle=\'Tourofheroes\';her... 查看详情

从类创建派生类型,但省略构造函数(打字稿)

】从类创建派生类型,但省略构造函数(打字稿)【英文标题】:Createaderivedtypefromclass,butomittheconstructor(typescript)【发布时间】:2020-02-2201:08:49【问题描述】:我有一个这样定义的接口和类:interfaceFooconstructor:typeofFoo;classFoostaticba... 查看详情

开玩笑的打字稿 - 模拟日期构造函数

】开玩笑的打字稿-模拟日期构造函数【英文标题】:jesttypescript-MockDateconstructor【发布时间】:2020-07-0917:28:45【问题描述】:我正在尝试模拟newDate()以返回特定日期。以下代码:constnow=newDate()jest.spyOn(global,\'Date\').mockImplementation(()... 查看详情

打字稿:通过传入命名参数的构造函数创建类?

】打字稿:通过传入命名参数的构造函数创建类?【英文标题】:Typescript:Createclassviaconstructorpassinginnamedparameters?【发布时间】:2018-01-1210:18:11【问题描述】:我有一个类,其中定义了带有3个参数的构造函数,这些参数都是可选... 查看详情

反应打字稿测试TypeError:MutationObserver不是构造函数

】反应打字稿测试TypeError:MutationObserver不是构造函数【英文标题】:reacttypescripttestingTypeError:MutationObserverisnotaconstructor【发布时间】:2020-07-1701:20:03【问题描述】:上周我使用create-react创建了一个React应用程序。我有一个简单的... 查看详情

如何在打字稿中使用 singleton() 在构造函数中传递值?

】如何在打字稿中使用singleton()在构造函数中传递值?【英文标题】:Howtopassvaluesinconstructorusingsigleton()intypescript?【发布时间】:2020-03-1412:38:52【问题描述】:我对如何在typescript中使用单例类在构造函数中传递值存有疑问。我的... 查看详情

如何在打字稿中使用可选参数调用类构造函数[重复]

】如何在打字稿中使用可选参数调用类构造函数[重复]【英文标题】:Howtocalltheclassconstructorwithoptionalparametersintypescript[duplicate]【发布时间】:2021-06-1904:25:24【问题描述】:exportdefaultclassAreaparam1:String;param2:String;param3:String;constructor... 查看详情

打字稿:将类数组的类型转换为构造类数组的类型

】打字稿:将类数组的类型转换为构造类数组的类型【英文标题】:Typescript:convertingtypeofarrayofclassestotypeofarrayofconstructedclasses【发布时间】:2022-01-2117:50:51【问题描述】:有一个问题我一直在努力解决。我有一个函数,里面放了... 查看详情

如果参数为空,则打字稿函数返回类型为空

】如果参数为空,则打字稿函数返回类型为空【英文标题】:Typescriptfunctionreturntypenullifparameternull【发布时间】:2019-06-3010:07:37【问题描述】:我想让Typescript知道,如果传递给函数的dbUser参数不为null,那么结果肯定不会为null。t... 查看详情

uuidv5 的打字稿声明,同时导出枚举和默认函数

】uuidv5的打字稿声明,同时导出枚举和默认函数【英文标题】:Typescriptdeclarationforuuidv5,exportbothenumanddefaultfunction【发布时间】:2017-05-2923:56:30【问题描述】:我正在尝试为uuidv5创建一个Typescript声明,这是我对第3方模块的第一个... 查看详情

打字稿函数接口

】打字稿函数接口【英文标题】:TypescriptFunctionInterface【发布时间】:2013-01-2615:40:08【问题描述】:为什么Typescript没有警告我我定义的函数与接口声明不匹配,但如果我尝试调用该函数,它会警告我。interfaceIFormatter(data:string,toU... 查看详情

再次:打字稿函数重载

】再次:打字稿函数重载【英文标题】:Onceagain:typescriptfunctionoverload【发布时间】:2019-07-0411:17:56【问题描述】:通常我可以掌握打字稿语言的大部分功能,但有时函数重载仍然相当具有挑战性。我无法理解为什么typescript编译... 查看详情

如何在打字稿中声明函数类型

】如何在打字稿中声明函数类型【英文标题】:Howtodeclareafunctiontypeintypescript【发布时间】:2019-05-0515:20:14【问题描述】:我正在使用打字稿并将一个函数传递给另一个函数。如果我有一个函数被传递给打字稿中的另一个函数,... 查看详情

打字稿重载箭头函数

】打字稿重载箭头函数【英文标题】:Typescriptoverloadarrowfunctions【发布时间】:2017-01-0409:13:59【问题描述】:所以我们可以这样做:exportfunctionmyMethod(param:number):numberexportfunctionmyMethod(param:string):stringexportfunctionmyMethod(param:string|numbe... 查看详情

打字稿、泛型和重载

】打字稿、泛型和重载【英文标题】:Typescript,genericsandoverloading【发布时间】:2021-10-0413:59:30【问题描述】:我正在努力在Typescript中实现一些我想重载的函数,这些函数也使用泛型。我被这个结果彻底搞糊涂了:*请注意,我已... 查看详情