打字稿。如何使用未导出的类型定义?
TypeScript. How to use not exported type definitions?
看看这个打字稿代码:
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;
}
}
"human" 属性 "Foo" class 中的问题。我无法将此变量的类型定义为来自 lib.ts.
的 "Human" 接口
在方法"diffWithError"中我犯了一个错误——在算术运算中使用了数字"age"和字符串"name",但是IDE和ts编译器都不知道这个,因为在这种情况下,"this.human.name" 的类型是 "any"
在方法"diffWithTypingAndAutocoplete"中我只使用了方法"getHuman"。 IDE 并且编译器知道方法结果的类型。这是 "Human" 界面和字段 "name" 是 "string"。此方法在编译源代码时会触发错误。
我在尝试导入 JS 库的 .d.ts 文件时发现了这个问题,但我无法导出所需的接口。每当我想定义类型(并且没有内联类型定义,如 { name: string, age:数字 })。
我不想创建未导出的 classes 的实例,我只想要类型检查和自动完成。
P.S。我试着写这个:
human: Human
编译器触发错误:"error TS2304: Cannot find name 'Human'"(预期行为)
P.S.S 我尝试使用三重斜杠指令来做到这一点:
///<reference path="./lib.ts" />
但这也行不通。
抱歉我的英语不好,感谢您的回答
您需要导出 Human
以便它在 index.ts
中可见并可用(如 HumanFactory
)。不要使用默认导出,而是 "named exports" 即试试这个
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;
}
}
更新
现在有了 conditional types 就可以在没有解决方法的情况下完成:
type Human = ReturnType<HumanFactory['getHuman']>
解决方法 TS < 2.8
如果您无法更改 lib.ts,您可以 "query" return 类型的 getHuman
函数。这有点棘手,因为打字稿目前没有为此提供任何直接的方法:
import HumanFactory from "./lib";
const dummyHuman = !true && new HumanFactory().getHuman();
type Human = typeof dummyHuman;
export class Foo {
human: Human;
// ...
}
!true &&
用于防止new HumanFactory().getHuman()
执行。
我找到了解决办法!
我制作文件 human-interface.ts 内容如下:
import HumanFactory from './lib';
const humanObject = new HumanFactory().getHuman();
type HumanType = typeof humanObject;
export default interface Human extends HumanType {}
在主文件中导入此接口不会执行创建 "HumanFactory" 并且类型检查工作正常。
感谢 typeof
的想法
在 TypeScript 2.8 中引入了 ReturnType<>
静态类型,这变得更容易了。
import HumanFactory from "./lib";
type Human = ReturnType<typeof HumanFactory.prototype.getHuman>
另见
看看这个打字稿代码:
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;
}
}
"human" 属性 "Foo" class 中的问题。我无法将此变量的类型定义为来自 lib.ts.
的 "Human" 接口在方法"diffWithError"中我犯了一个错误——在算术运算中使用了数字"age"和字符串"name",但是IDE和ts编译器都不知道这个,因为在这种情况下,"this.human.name" 的类型是 "any"
在方法"diffWithTypingAndAutocoplete"中我只使用了方法"getHuman"。 IDE 并且编译器知道方法结果的类型。这是 "Human" 界面和字段 "name" 是 "string"。此方法在编译源代码时会触发错误。
我在尝试导入 JS 库的 .d.ts 文件时发现了这个问题,但我无法导出所需的接口。每当我想定义类型(并且没有内联类型定义,如 { name: string, age:数字 })。
我不想创建未导出的 classes 的实例,我只想要类型检查和自动完成。
P.S。我试着写这个:
human: Human
编译器触发错误:"error TS2304: Cannot find name 'Human'"(预期行为)
P.S.S 我尝试使用三重斜杠指令来做到这一点:
///<reference path="./lib.ts" />
但这也行不通。
抱歉我的英语不好,感谢您的回答
您需要导出 Human
以便它在 index.ts
中可见并可用(如 HumanFactory
)。不要使用默认导出,而是 "named exports" 即试试这个
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;
}
}
更新
现在有了 conditional types 就可以在没有解决方法的情况下完成:
type Human = ReturnType<HumanFactory['getHuman']>
解决方法 TS < 2.8
如果您无法更改 lib.ts,您可以 "query" return 类型的 getHuman
函数。这有点棘手,因为打字稿目前没有为此提供任何直接的方法:
import HumanFactory from "./lib";
const dummyHuman = !true && new HumanFactory().getHuman();
type Human = typeof dummyHuman;
export class Foo {
human: Human;
// ...
}
!true &&
用于防止new HumanFactory().getHuman()
执行。
我找到了解决办法!
我制作文件 human-interface.ts 内容如下:
import HumanFactory from './lib';
const humanObject = new HumanFactory().getHuman();
type HumanType = typeof humanObject;
export default interface Human extends HumanType {}
在主文件中导入此接口不会执行创建 "HumanFactory" 并且类型检查工作正常。
感谢 typeof
在 TypeScript 2.8 中引入了 ReturnType<>
静态类型,这变得更容易了。
import HumanFactory from "./lib";
type Human = ReturnType<typeof HumanFactory.prototype.getHuman>
另见