[英]typescript: 'new' call to function
最近我想到将我的一个副项目转换成 Typescript。 但是我在使用 new 调用函数时遇到了麻烦。
我正在尝试调用从另一个文件导入的函数,如下所示:
// Function in 'file.js'
function Foo() {
this.x = 1;
this.y = 2;
}
Foo.prototype.set = function() {
return this.x + this.y;
};
export { Foo };
// Function in another file calling Foo
import { Foo } from './file';
function getSum() {
let foo = new Foo(); // I got the below error here!!!
foo.set();
}
当我尝试键入此内容时,出现此错误: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.
.
查看打字稿文档,我理解调用签名应该写成如下:
type SomeConstructor = {
new (s: string): SomeObject;
};
function fn(ctor: SomeConstructor) {
return new ctor("hello");
}
但我不知道如何将上述类型应用于我的“Foo”函数。 我试图将构造签名应用于函数,但无法正确放置。
// Function in 'file.js' --> renamed to 'file.tsx'
type FooType = {
x: number,
y: number,
};
type FooConstructor = {
new (): FooType
};
function Foo(this: FooType) { // How do I add FooConstructor to this?
this.x = 1;
this.y = 2;
}
Foo.prototype.set = function(): number {
return this.x + this.y;
};
我无法在导出/导入或函数调用期间应用它。 以下所有抛出错误。
export { Foo: FooConstructor };
import { Foo: FooConstructor } from './file';
let foo = new Foo() as FooConstructor;
那么我是否应该将 Foo 函数更改为一个类,这是唯一可能的输入方式吗?。 我看到很多博客展示了如何键入一个类,但即使使用这种方法,我也收到一条错误消息,说Type 'FooType' is not assignable to type 'FooConstructor'
。
我在这里迷路了。 任何帮助表示赞赏!
编辑:我的 File.ts 现在看起来像这样:
我在 File.ts 文件中添加声明,如下所示:
type FooType = {
x: number,
y: number,
};
declare class Foo {
constructor();
x: number;
y: number;
setHeader(): number;
}
function Foo(this: FooType) {
this.x = 1;
this.y = 2;
}
Foo.prototype.set = function(): number {
return this.x + this.y;
};
export { Foo };
如果您有需要作为 TypeScript 类型化的遗留 JavaScript 代码,您可以创建仅包含类型的定义文件(运行时代码保留在 JavaScript 中)。
在最初的示例中,一个包含用 ES5 编写的Foo
类的file.js
文件可能有一个包含以下内容的同级file.d.ts
:
// file.d.ts
export declare class Foo {
x: number;
y: number;
constructor();
set(): number;
}
// Any other TypeScript file
import { Foo } from 'any/path/file';
let foo = new Foo(); // Foo
const num = foo.set(); // number
所以问题中的错误是将遗留的 JavaScript 代码移动到 TypeScript 文件(TypeScript 不支持 ES5 作为源代码,至少对于类)而不是编写定义文件。
注意:在这个具体的例子中, constructor();
是多余的,因为它是隐式默认构造函数,但您可以使用任意数量、任意类型的参数键入构造函数,甚至可以利用函数重载来定义多个签名。
作为对“如何键入一个不是作为 ES6 类编写的新函数?”的更一般的回答,也可以在任何 TypeScript type
或interface
中使用new
关键字:
interface Foo {
x: number;
y: number;
set(): number;
}
type Constructor<T> = new (...args: any[]) => T;
declare const newableFunction: Constructor<Foo>;
const obj = new newableFunction(); // Foo
同样在这种情况下,如果实现是一个普通的旧函数,最好将它编写在一个单独的 JavaScript 文件中,否则编译器会抱怨声明的类型与实现的类型不匹配。
更进一步,考虑这种混合函数,它可以使用或不使用new
关键字来调用:
// Function in 'file.js'
function newableFunction() {
const self = Object.getPrototypeOf(this) === newableFunction.prototype ? this : {};
self.x = 1;
self.y = 2;
self.get = function () {
return self.x + self.y;
}
return self;
}
这个特殊函数可以这样输入:
interface Foo {
x: number;
y: number;
get(): number;
}
interface Constructor<T> {
(...args: any[]): T
new (...args: any[]): T
}
export const newableFunction: Constructor<Foo>;
使用示例:
import { newableFunction } from './file';
const foo1 = newableFunction(); // Foo
const foo2 = new newableFunction(); // Foo
这种构造也可以在lib.es5.d.ts
原生 JavaScript 类型中找到,例如Number
构造函数:
interface NumberConstructor {
new(value?: any): Number;
(value?: any): number;
// ...
正式地,Typescript 决定不为这种有效的“老派”JavaScript 提供语法支持。 他们更喜欢class
语法。
但是,有可能使它工作,从我以前的回答中复制:
// Only instance members here.
export interface Circle { // Name the interface with the same than the var.
radius: number;
area: () => number;
perimeter: () => number;
}
// You could define static members here.
interface CircleConstructor {
new(radius: number): Circle;
}
export const Circle = function(this: Circle, radius: number) {
const pi = 3.14;
this.radius = radius;
this.area = function () {
return pi * radius * radius
}
this.perimeter = function () {
return 2 * pi * radius;
}
} as unknown /*as any*/ as CircleConstructor; // Note the trust-me casting
const c = new Circle(3); // okay
这带来了一些问题。 例如,它正在使用any
被禁止的类型,或者必须使用as
操作符,这是非常丑陋的。 作为改进,我使用了unknown
而不是any
但核心问题仍然存在。 这使得 lint 工具不会报错,所以它比any
有了很大的改进。
这是迄今为止我找到的最佳解决方案。 Typescript 开发者意识到了这一点,但他们决定不为这种“语法”提供支持。
解决这种情况的唯一方法是将以下 function 转换为 class:
function Foo(this: FooType) { // How do I add FooConstructor to this?
this.x = 1;
this.y = 2;
}
Foo.prototype.set = function(): number {
return this.x + this.y;
};
至:
class Foo() {
x: number;
y: number;
constructor() {
this.x = 1;
this.y = 2;
}
set (): number {
return this.x + this.y;
}
}
>Adjunto mi código espero ayude
>Para ejecutar solo realice new Functions()
>para llamar a la clase internamente se ejecutar
> el constructor de Functions
type SomeConstructor = {
new (s:string):SomeObject;
}
type SomeObject = any;
export class Example{
constructor(s:string){
console.log(s)
}
}
export class Functions {
constructor(){
const callable = (someObject:SomeObject)=>{
return someObject;
}
this.fnSomeConstructor(callable(new Example("Hola")));
}
fnSomeConstructor(ctor: SomeConstructor) {
return new func(func.name);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.