打字稿。如何使用不导出的类型定义?

时间:2017-10-15 12:22:05

标签: typescript typescript-typings

看看这个打字稿代码:

lib.ts

interface Human {
    name: string;
    age: number;
}

export default class HumanFactory {
    getHuman(): Human {
        return {
            name: "John",
            age: 22,
        }
    }
}

index.ts

import HumanFactory from "./lib";

export class Foo {
    human: any;

    constructor() {
        const factory = new HumanFactory();
        this.human = factory.getHuman();
    }

    diffWithError(age: number): number {
        return age - this.human.name;
    }

    diffWithTypingAndAutocoplete(age: number): number {
        const factory = new HumanFactory();
        return age - factory.getHuman().name;
    }
}

“Foo”类的“人”属性问题。我无法将此变量的类型定义为lib.ts中的“Human”接口。

在方法“diffWithError”中我犯了一个错误 - 在算术运算中使用数字“age”和字符串“name”,但IDE和ts编译器都不知道这一点,因为在这个上下文中,类型为“this.human.name” “是”任何“

在方法“diffWithTypingAndAutocoplete”中我只使用方法“getHuman”。 IDE和编译器知道方法结果的类型。这是“人”界面,字段“名称”是“字符串”。此方法在编译源时会触发错误。

当我尝试导入JS lib的.d.ts文件时,我发现了这个问题,我无法导出所需的界面。每当我想要定义类型(并且没有内联类型定义,如{name:string,age:number})时,我可以以某种方式定义有效类型的“人类”属性,而无需复制和粘贴“Human”接口的代码。

我不想创建未导出的类的实例,我只想要类型检查和自动完成。

P.S。我试着写下这个:

human: Human

编译器触发错误:“错误TS2304:找不到名字'人''(预期行为)

P.S.S我尝试使用三次斜杠指令:

///<reference path="./lib.ts" />

但这也不起作用。

抱歉我的英文不好,谢谢你的回答

4 个答案:

答案 0 :(得分:3)

我找到了解决方案!

我使用以下内容制作文件human-interface.ts:

import HumanFactory from './lib';

const humanObject = new HumanFactory().getHuman();
type HumanType = typeof humanObject;

export default interface Human extends HumanType {}

在主文件中导入此接口不会执行&#34; HumanFactory&#34;和类型检查工作正常。

感谢typeof

的想法

答案 1 :(得分:1)

您需要导出Human,以便index.ts也可以显示(和HumanFactory)。不要使用默认导出,而是使用名为exports&#34;即试试这个

export interface Human {
    name: string;
    age: number;
}

export class HumanFactory {
    getHuman(): Human {
        return {
            name: "John",
            age: 22,
        }
    }
}

index.ts

import { Human, HumanFactory} from "./lib";

**编辑**

如果你不能改变lib.d.ts然后重新定义Human并使用双重铸造,即

import HumanFactory from "./lib";

interface Human {
    name: string;
    age: number;
}

export class Foo {
    human: Human;  // <= change here

    constructor() {
        const factory = new HumanFactory();
        this.human = factory.getHuman() as any as Human;  // <= double casting 
    }

    diffWithError(age: number): number {
        return age - this.human.name;
    }

    diffWithTypingAndAutocoplete(age: number): number {
        const factory = new HumanFactory();
        return age - factory.getHuman().name;
    }
}

答案 2 :(得分:0)

<强>更新

现在有了conditional types,可以在没有解决方法的情况下完成:

type Human = ReturnType<HumanFactory['getHuman']>
TS&lt; 解决方法 2.8

如果您无法更改 lib.ts ,则可以“查询”getHuman函数的返回类型。这有点棘手,因为typescript目前没有为此提供任何直接的方法:

import HumanFactory from "./lib";

const dummyHuman = !true && new HumanFactory().getHuman();
type Human = typeof dummyHuman;

export class Foo {
  human: Human;

  // ...
}

!true &&用于阻止new HumanFactory().getHuman()执行。

答案 3 :(得分:0)

通过TypeScript 2.8中的ReturnType<>静态类型的引入,这变得更加容易。

import HumanFactory from "./lib";
type Human = ReturnType<typeof HumanFactory.prototype.getHuman>

另请参阅https://stackoverflow.com/a/43053162