我找到了很多例子,并尝试将模块分成几个文件。所以我得到那个,非常方便。但是出于同样的原因,有时候分割课程也很实际。假设我有几种方法,我不想将所有内容都塞进一个长文件中。
我正在寻找类似于C#中部分声明的内容。
答案 0 :(得分:19)
你不能。
有一个功能请求要实现部分类,首先在CodePlex上,然后在GitHub上,但是on 2017-04-04它被声明为超出范围。给出了很多理由,主要的理由是他们希望尽可能避免偏离ES6:
TypeScript 已经具有太多特定于TS的类功能[...]添加另一个特定于TS的类功能是骆驼背上的另一根稻草,如果我们应该避免能够。 [...]因此,如果某些场景确实将其从公园中推出以添加部分课程,那么该场景应该能够通过TC39流程证明自己的合理性。
答案 1 :(得分:18)
我使用它(适用于打字稿2.2.2):
class BigClass implements BigClassPartOne, BigClassPartTwo {
// only public members are accessible in the
// class parts!
constructor(public secret: string) { }
// this is ugly-ish, but it works!
methodOne = BigClassPartOne.prototype.methodOne;
methodTwo = BigClassPartTwo.prototype.methodTwo;
}
class BigClassPartOne {
methodOne(this: BigClass) {
return this.methodTwo();
}
}
class BigClassPartTwo {
methodTwo(this: BigClass) {
return this.secret;
}
}
答案 2 :(得分:12)
Lately I use this pattern:
class BigClass {
public getValue = getValue;
public setValue = setValue;
protected value = "a-value";
}
function getValue(this: BigClass) {
return this.value;
}
function setValue(this: BigClass, value: string ) {
this.value = value;
}
Often I move the functions in seperate files, for a clean and scalable setup!
答案 3 :(得分:3)
在转换使用' prototype'的大型旧多文件javascript类时,我使用简单的子类化。到多个打字稿文件:
bigclassbase.ts:
class BigClassBase {
methodOne() {
return 1;
}
}
export { BigClassBase }
bigclass.ts:
import { BigClassBase } from './bigclassbase'
class BigClass extends BigClassBase {
methodTwo() {
return 2;
}
}
您可以在任何其他打字稿文件中导入BigClass。
答案 4 :(得分:2)
您可以使用multi file namespaces。
Validation.ts:
namespace Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}
}
LettersOnlyValidator.ts(使用上面的StringValidator):
/// <reference path="Validation.ts" />
namespace Validation {
const lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}
}
Test.ts(同时使用上面的StringValidator和LettersOnlyValidator):
/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />
// Some samples to try
let strings = ["Hello", "101"];
// Validators to use
let validators: { [s: string]: Validation.StringValidator; } = {};
validators["Letters only"] = new Validation.LettersOnlyValidator();
答案 5 :(得分:1)
提议模式的修改版本。
// temp.ts contents
import {getValue, setValue} from "./temp2";
export class BigClass {
// @ts-ignore - to ignore TS2564: Property 'getValue' has no initializer and is not definitely assigned in the constructor.
public getValue:typeof getValue;
// @ts-ignore - to ignore TS2564: Property 'setValue' has no initializer and is not definitely assigned in the constructor.
public setValue:typeof setValue;
protected value = "a-value";
}
BigClass.prototype.getValue = getValue;
BigClass.prototype.setValue = setValue;
//======================================================================
// temp2.ts contents
import { BigClass } from "./temp";
export function getValue(this: BigClass) {
return this.value;
}
export function setValue(this: BigClass, value: string ) {
this.value = value;
}
优点
缺点
其他解的性质相同。
答案 6 :(得分:0)
我们可以使用prototype
和Interface
定义逐步扩展类方法:
import login from './login';
import staffMe from './staff-me';
interface StaffAPI {
login(this: StaffAPI, args: LoginArgs): Promise<boolean>;
staffsMe(this: StaffAPI): Promise<StaffsMeResponse>;
}
class StaffAPI {
// class body
}
StaffAPI.prototype.login = login;
StaffAPI.prototype.staffsMe = staffsMe;
export default StaffAPI;
答案 7 :(得分:0)
为什么不只使用js已经附带的Function.call
。
class-a.ts
Class ClassA {
bitten: false;
constructor() {
console.log("Bitten: ", this.bitten);
}
biteMe = () => biteMe.call(this);
}
和其他文件bite-me.ts
export function biteMe(this: ClassA) {
// do some stuff
// here this refers to ClassA.prototype
this.bitten = true;
console.log("Bitten: ", this.bitten);
}
//使用它
const state = new ClassA();
// Bitten: false
state.biteMe();
// Bitten: true
有关更多信息,请查看$setUnion
的定义答案 8 :(得分:0)
我个人使用 @partial 装饰器作为一种简化的语法,可以帮助将单个类的功能划分为多个 ??? 类文件 ... https://github.com/mustafah/partials
答案 9 :(得分:0)
模块让你从另一个文件扩展一个打字稿类:
user.ts
export class User {
name: string;
}
import './user-talk';
user-talk.ts
import { User } from './user';
class UserTalk {
talk (this:User) {
console.log(`${this.name} says relax`);
}
}
User.prototype.sayHi = UserTalk.prototype.sayHi;
declare module './user' {
interface User extends UserTalk { }
}
用法:
import { User } from './user';
const u = new User();
u.name = 'Frankie';
u.talk();
> Frankie says relax
如果你有很多方法,你可以试试这个:
// user.ts
export class User {
static extend (cls:any) {
for (const key of Object.getOwnPropertyNames(cls.prototype)) {
if (key !== 'constructor') {
this.prototype[key] = cls.prototype[key];
}
}
}
...
}
// user-talk.ts
...
User.extend(UserTalk);
或者将子类添加到原型链中:
...
static extend (cls:any) {
let prototype:any = this;
while (true) {
const next = prototype.prototype.__proto__;
if (next === Object.prototype) break;
prototype = next;
}
prototype.prototype.__proto__ = cls.prototype;
}
答案 10 :(得分:-1)
要添加到@Elmer的solution,我添加了以下内容,使其可以在单独的文件中工作。
some-function-service-helper.ts
import { SomeFunctionService } from "./some-function-service";
export function calculateValue1(this: SomeFunctionService) {
...
}
some-function-service.ts
import * as helper from './some-function-service-helper';
@Injectable({
providedIn: 'root'
})
export class SomeFunctionService {
calculateValue1 = helper.calculateValue1; // helper function delcaration used for getNewItem
public getNewItem() {
var one = this.calculateValue1();
}