我可以修复一个错误,但另一个我不知道如何修复,因为我找不到这种类型的原始类型。因为类型只存在于打字稿中,在 javascript 中没有类型。字符串的类型is not reference to javascript String class,如果要让typescript正确编译必须string
在typesides中使用。like foo:string
nor foo:String
;当你编写let string: String = String;
编译器报告错误时,因为左侧ref一个类型,右侧ref一个String构造函数,它们是不同。对不起,我的英语不好,所以我希望你能理解我所说的。难以想象,打字稿编译器会将String类型编译成String类到.js文件中,你可以使用tsc
编译js文件看看结果。第三次测试可以运行,我认为用户定义的类扮演两个角色:the instance of the class
&the type of the class
.but Date
&String
将type
/constructor function
分成两部分:type
作为接口“字符串”,constructor function
通过全局变量StringConstructor
import 'reflect-metadata';
import 'core-js/es7/reflect';
function Test(expectedType: any) {
return function (target: any, key: string): void {
let type = Reflect.getOwnMetadata('design:type', target, key);
test(`${target.constructor.name} ${key}'s type should be ${expectedType.name} but was ${type.name}!`, () => {
expect(type).toBe(expectedType);
});
}
}
class TestClass {
}
class ReflectMetadataTest {
@Test(String) item: string;
@Test(Date) date: Date;
@Test(TestClass) instance: TestClass;
}
test('metadata', () => {
let type = String;
let clazz = ReflectMetadataTest.prototype;
let decorator: any = Reflect.metadata("foo", type);
decorator(clazz, 'item', void 0);
expect(Reflect.getMetadata('foo', clazz, 'item')).toBe(type);
});
也许下面的两个测试可以回答你的问题
Date
&是遗留系统。String
它们通过函数或类声明定义类,因此打字稿无法获取类型信息。Object
如果你在内存中运行打字稿,打字稿会传递类型,但是,当将tsc
.ts 编译成 .js 时,它会保留与下面的测试type
相同,constructor function
假设该函数Foo
是一个基于函数的类,打字稿无法推断Foo
类型,因此它会发出一个Object
到 Reflect.metadata(),但是当您将测试文件编译为 .js 时通过tsc
,编译器将保留type
to constructor function
。
import 'reflect-metadata';
import 'core-js/es7/reflect';
function Test(expectedType: any) {
return function (target: any, key: string): void {
let type = Reflect.getOwnMetadata('design:type', target, key);
test(`${target.constructor.name} ${key}'s type should be ${expectedType.name} but was ${type.name}!`, () => {
expect(type).toBe(expectedType);
});
}
}
function Foo() {
}
interface Foo {
}
class ReflectMetadataTest {
@Test(Foo/*ref function*/) foo: Foo/*ref interface*/;
}
test('metadata', () => {
let type = Foo;
let clazz = ReflectMetadataTest.prototype;
let decorator: any = Reflect.metadata("foo", type);
decorator(clazz, 'item', void 0);
expect(Reflect.getMetadata('foo', clazz, 'item')).toBe(type);
});
概括
如果您想让元数据在 .js 和 .ts 中正常工作,您必须使用a wrapper class
/定义。a subclass
legacy function based class
import 'reflect-metadata';
import 'core-js/es7/reflect';
function Test(expectedType: any, same: boolean) {
return function (target: any, key: string): void {
let declaredType = Reflect.getOwnMetadata('design:type', target, key);
test(`${target.constructor.name} ${key}'s type should ${same ? '' : 'not '}be \`${expectedType.name}\` & declared type was \`${declaredType.name}\`!`, () => {
expect(declaredType == expectedType).toBe(same);
});
}
}
function Foo() {
}
interface Foo {
}
class MyDate extends Date{
}
class ReflectMetadataTest {
// this test always false even if you compile .ts it into .js file
@Test(Foo/*ref function*/, false) foo: Foo/*ref interface*/;
//this test is true when you compile .ts it into .js file
@Test(Date, false) date: Date;
@Test(String, false) String: String;
@Test(Number, false) Number: Number;
//this test is always true both in .ts & .js
@Test(Number, true) number: number;
@Test(Boolean, true) boolean: boolean;
@Test(String, true) string: string;
@Test(MyDate, true) myDate: MyDate;
@Test(ReflectMetadataTest, true) test: ReflectMetadataTest;
}