TypeScript-bindningar för klass fungerar inte?
Jag har en definitionsfil, låt oss kalla den someclass.d.ts som ser mer eller mindre ut så här:
declare class SomeClass {
static write : {
doThing(name: string) : string
}
static get : {
doThing2(count: number): string
}
}
Detta matchar den faktiska klassen i someclass.ts
export default class SomeClass {
static write = {
doThing(name) {
return "foo1";
}
}
static get = {
doThing2(count) {
return "foo2";
}
}
}
Och sedan i min mainThing.ts, som faktiskt använder SomeClass:
/// <reference types="./someclass" />
import SomeClass from './someclass.ts';
SomeClass.write.doThing("dummyexample");
Om jag hovrar över doThing i mainThing.ts/someclass.ts i VSCode, beter det sig som om allt är implicit any-typat, vilket säger mig att jag gör något fel. Jag vet bara inte vad.
Jag gissar att jag gör deklarationen fel för de där klassmedlemsblocken, men jag är inte säker på vad rätt sätt att göra det är; att försöka göra static write={ verkar få det att leta efter funktionskroppar...
Vad gör jag för fel? Tack!
Redigera: Jag är medveten om att jag inte är skyldig att ha en separat definitionsfil, men jag vill göra det i namn av läsbar kod. Den verkliga signaturen för doThing ser mer ut som
doThing({ name, email, password, p4, p5, p6 }
: { name: string, email: string, password: string, p4: string, p5: number, p6: string })
: Type1<Type2<Type3>>
Redigera 2: Dessutom behöver SomeClass egentligen inte vara en klass... kanske TypeScript-namespace (eller något annat) skulle vara mer lämpligt? Jag försöker mest organisera ett stort antal hjälpmetoder på ett sätt som inte är överväldigande. Allt är avsiktligt statiskt av denna anledning; det är ingen mening att instansiera SomeClass när den inte har något tillstånd.
Svar #1
.d.ts-deklarationsfilen är avsedd att typannotera .js-fil, inte .ts-fil.
Jag kan se att du försöker använda Java-konventionen här. Grejen är att JS class är ganska annorlunda än Java class. TS är designat för JS så det kommer inte att fungera som du förväntar dig. Även om du kan använda .d.ts med .ts-fil, är användningen som involverar class mycket omständlig, så pass att det motverkar syftet med läsbar kod.
Mitt förslag på ditt problem är att använda enkel objekt istället för class-static par, eftersom JS class egentligen är syntakssocker för objekt.
someclass.d.ts
declare interface SomeClass {
write: {
doThing(name: string): string;
};
get: {
doThing2(count: number): string;
};
}
someclass.ts
const SomeClass: SomeClass = {
write: {
doThing(name) {
return "foo1";
}
},
get: {
doThing2(count) {
return "foo2";
}
}
};
export default SomeClass;
mainThing.ts
import SomeClass from './someclass.ts';
SomeClass.write.doThing(1);
// [TS ERROR] Argument of type '1' is not assignable to parameter of type 'string'.
Sidnot:
Jag sa tidigare att användning som involverar class är mödosam. Här är hur man gör det om du verkligen vill använda class-static:
someclass.d.ts
declare abstract class SomeAbstractClass {
static write: {
doThing(name: string): string;
}
}
someclass.ts
export default class SomeClass extends SomeAbstractClass {
static write = {
// you still need to re-write the function signature in class impl
doThing(name: string) {
return "foo1";
}
// all it does is just to warn you when you accidentally write:
doThing(name: number) { // ERROR: should be string not number
return "foo1";
}
}
}
Du kan inte använda class SomeClass implements SomeClassInterface, eftersom implements nyckelordet endast styr instanssidan av klassen, inte den statiska sidan.
