View difference between Paste ID: VT3fStx7 and v8Rf6g6Y
SHOW: | | - or go back to the newest paste.
1
// TypeScript中的静态函数的interface的变通实现方法
2
// 进一步参考:https://stackoverflow.com/questions/33719459/how-to-declare-an-interface-with-static-method?lq=1
3
4
/**
5
 * TypeScript Constructor Interfaces Proposal
6
 *
7
 * Author: Reed Spool
8
 */
9
10
/**
11
 * Root interface for Constructor Interfaces. This is a workaround for
12
 * TypeScript's lack of "static" methods for classes.
13
 * 
14
 * Based on StackOverflow user chris's solution. See 
15
 * https://stackoverflow.com/a/43484801/1037165 
16
 * 
17
 * @interface IConstructor
18
 * @template InstanceInterface
19
 */
20
interface IConstructor<InstanceInterface>
21
{
22
  /**
23
   * Explicitly typed constructor is required, so make an extremely permissive
24
   * declaration that can be refined in subclasses.
25
   * 
26
   * @constructor
27
   */
28
  new (...args : any[]) : InstanceInterface;
29
}
30
31
/** 
32
 * That's ALL for the definition. What follows is a comprehensive usage
33
 * example.
34
 */
35
36
// Create a Constructor Interface by extending IConstructor and
37
// specifiying your Instance Interface. Keep your class open for
38
// extension with "T extends ...".
39
interface CMyClass<T extends IMyClass> extends IConstructor<T>
40
{
41
  // Specify constructor parameters safely, staying open for extension
42
  // by specifying any variatic arguments. You don't need to specify
43
  // a constructor though.
44
  new (instanceValue : string, ...args : any[]) : T;
45
46
  // Properties on Constructor Interfaces can be accessed by the
47
  // Class object.
48
  aClassProperty : string;
49
50
  // This is useful for static factory methods.
51
  aClassMethod () : T
52
}
53
54
// Create a normal Instance Interface. IConstructor doesn't require 
55
// or restrict anything here. You could use anything, including
56
// `Object` or `any`
57
interface IMyClass 
58
{
59
}
60
61
// This is the hackish part: Your class must be anonymous so that
62
// you can specify the type of the variable that holds it. So make a 
63
// `const` variable of your Constructor Interface's type set to a new
64
// anonymous class which implements your Instance Interface.
65
export const MyClass : CMyClass<IMyClass> = class implements IMyClass
66
{
67
  // The constructor must satisfy CMyClass's `new` signature.
68
  constructor (instanceValue : string, ...args : any[])
69
  {
70
  }
71
72
  // We can use the built-in JS `static` keyword to satisfy the interface
73
  // of CMyClass
74
  static aClassProperty : string = "myProp";
75
  static aClassMethod () : IMyClass { return new MyClass(); }
76
}