mirror of
https://github.com/FlipsideCrypto/DefinitelyTyped.git
synced 2026-02-06 19:07:08 +00:00
* stampit 4.3 * fix `Error: stampit: Older version 3 must have a path mapping for itself.` * fix`baseUrl` & `typeRoots` * Some dtslint compliance * header fix * enhance * tests * tslint:disable * naming * fix refs/props changes + ExtendedDescriptor * more $ExpectType tests * Tentative `MethodMap` fix * Updated `MethodMap`tests * additional testing (failing) * fix `Composable` signature
341 lines
8.2 KiB
TypeScript
341 lines
8.2 KiB
TypeScript
/** Import 'stampit' module */
|
|
import stampit from 'stampit';
|
|
|
|
/** Import 'stampit' as ... module */
|
|
// import * as Stamp from 'stampit';
|
|
|
|
/** selective import from module */
|
|
// import {
|
|
// compose,
|
|
// composers,
|
|
// conf,
|
|
// configuration,
|
|
// deepConf,
|
|
// deepConfiguration,
|
|
// deepProperties,
|
|
// deepProps,
|
|
// deepStatics,
|
|
// init,
|
|
// initializers,
|
|
// methods,
|
|
// properties,
|
|
// propertyDescriptors,
|
|
// props,
|
|
// staticDeepProperties,
|
|
// staticProperties,
|
|
// staticPropertyDescriptors,
|
|
// version,
|
|
// } from 'stampit';
|
|
|
|
const a = stampit().init(function(options) {
|
|
const a = options.args[0];
|
|
this.getA = () => {
|
|
return a;
|
|
};
|
|
});
|
|
a(); // Object -- so far so good.
|
|
a().getA(); // "a"
|
|
|
|
const b = stampit().init(function() {
|
|
const a = 'b';
|
|
this.getB = () => {
|
|
return a;
|
|
};
|
|
});
|
|
|
|
const c = stampit.compose(a, b);
|
|
const foo = c(); // we won't throw this one away...
|
|
foo.getA(); // "a"
|
|
foo.getB(); // "b"
|
|
|
|
// Here's a mixin with public methods, and some props:
|
|
const membership = stampit({
|
|
methods: {
|
|
members: {
|
|
itCanBe: "anything",
|
|
},
|
|
myMembers: {},
|
|
dbConnString: "pgs://data.local",
|
|
MY_LIMIT: 100,
|
|
myRegExp: /foobar/g,
|
|
add(member: any) {
|
|
this.members[member.name] = member;
|
|
return this;
|
|
},
|
|
getMember(name: any) {
|
|
return this.members[name];
|
|
}
|
|
},
|
|
props: {
|
|
members: {}
|
|
}
|
|
});
|
|
|
|
// Let's set some defaults:
|
|
const defaults = stampit().props({
|
|
name: 'The Saloon',
|
|
specials: 'Whisky, Gin, Tequila'
|
|
});
|
|
|
|
// Classical inheritance has nothing on this. No parent/child coupling. No deep inheritance hierarchies.
|
|
// Just good, clean code reusability.
|
|
const bar = stampit.compose(defaults, membership);
|
|
// Note that you can override props on instantiation:
|
|
const myBar = bar({ name: 'Moe\'s' });
|
|
// Silly, but proves that everything is as it should be.
|
|
myBar.add({ name: 'Homer' }).open().getMember('Homer');
|
|
|
|
const myStamp = stampit().methods({
|
|
foo() {
|
|
return 'foo';
|
|
},
|
|
methodOverride() {
|
|
return false;
|
|
},
|
|
myMembers: {},
|
|
dbConnString: "pgs://data.local",
|
|
MY_LIMIT: 100,
|
|
myRegExp: /foobar/g,
|
|
}).methods({
|
|
bar() {
|
|
return 'bar';
|
|
},
|
|
methodOverride() {
|
|
return true;
|
|
},
|
|
myMembers: {},
|
|
dbConnString: "pgs://data.local",
|
|
MY_LIMIT: 100,
|
|
myRegExp: /foobar/g,
|
|
});
|
|
|
|
myStamp.deepProps({
|
|
foo: { bar: 'bar' },
|
|
refsOverride: false
|
|
}).props({
|
|
bar: 'bar',
|
|
refsOverride: true
|
|
});
|
|
|
|
myStamp.init(function() {
|
|
const secret = 'foo';
|
|
|
|
this.getSecret = () => {
|
|
return secret;
|
|
};
|
|
}).init(function() {
|
|
this.a = true;
|
|
}).init(function() {
|
|
this.b = true;
|
|
}, function() {
|
|
this.c = true;
|
|
});
|
|
|
|
let obj = myStamp.create();
|
|
obj.getSecret && obj.a && obj.b && obj.c; // true
|
|
|
|
const newStamp = stampit({ props: { defaultNum: 1 } }).compose(myStamp);
|
|
|
|
const obj1 = stampit().methods({
|
|
a() {
|
|
return 'a';
|
|
},
|
|
myMembers: {},
|
|
dbConnString: "pgs://data.local",
|
|
MY_LIMIT: 100,
|
|
myRegExp: /foobar/g,
|
|
}, {
|
|
b() {
|
|
return 'b';
|
|
},
|
|
myMembers: {},
|
|
dbConnString: "pgs://data.local",
|
|
MY_LIMIT: 100,
|
|
myRegExp: /foobar/g,
|
|
}).create();
|
|
|
|
const obj2 = stampit().props({
|
|
a: 'a'
|
|
}, {
|
|
b: 'b'
|
|
}).create();
|
|
|
|
obj = defaults.compose(newStamp, membership).create();
|
|
|
|
// The old constructor / class thing...
|
|
const Constructor = function Constructor() {
|
|
this.thing = 'initialized';
|
|
};
|
|
Constructor.prototype.foo = function foo() {
|
|
return 'foo';
|
|
};
|
|
|
|
// A new stamp to compose with...
|
|
const newskool = stampit().methods({
|
|
bar: function bar() {
|
|
return 'bar';
|
|
},
|
|
myMembers: {},
|
|
dbConnString: "pgs://data.local",
|
|
MY_LIMIT: 100,
|
|
myRegExp: /foobar/g,
|
|
// your methods here...
|
|
}).init(function() {
|
|
this.baz = 'baz';
|
|
});
|
|
|
|
// Now you can compose those old constructors just like you could
|
|
// with any other stamp...
|
|
const myThing = stampit.compose(newskool);
|
|
|
|
const t = myThing();
|
|
|
|
t.thing; // 'initialized',
|
|
|
|
t.foo(); // 'foo',
|
|
|
|
t.bar(); // 'bar'
|
|
|
|
interface SomeStampInstance {
|
|
a: string;
|
|
b: string;
|
|
}
|
|
|
|
// Test import of stamp type
|
|
interface SomeStamp extends stampit.Stamp<SomeStampInstance> {
|
|
(params: { a: number; b: boolean}): SomeStampInstance;
|
|
}
|
|
|
|
const SomeStamp = stampit<SomeStamp>()
|
|
.init(function(params: { a: number; b: boolean}) {
|
|
this.a = '' + a; // this SomeStampInstance
|
|
this.b = '' + b;
|
|
});
|
|
|
|
SomeStamp({ a: 1, b: false }); // $ExpectType SomeStampInstance
|
|
SomeStamp({ a: 1, b: false }).a; // $ExpectType string
|
|
|
|
const d: stampit.ExtendedDescriptor<{}> = {
|
|
methods: {},
|
|
properties: {},
|
|
deepProperties: {},
|
|
propertyDescriptors: {},
|
|
initializers: [],
|
|
staticProperties: {},
|
|
staticDeepProperties: {},
|
|
staticPropertyDescriptors: {},
|
|
composers: [],
|
|
configuration: {},
|
|
deepConfiguration: {},
|
|
name: '',
|
|
// shorthands
|
|
props: {},
|
|
deepProps: {},
|
|
init: [],
|
|
statics: {},
|
|
deepStatics: {},
|
|
conf: {},
|
|
deepConf: {},
|
|
};
|
|
|
|
// The `.compose()` method
|
|
const compose = stampit.compose; // $ExpectType typeof stampit
|
|
|
|
const stampUntyped = compose(); // $ExpectType Stamp<any>
|
|
stampUntyped(); // $ExpectType any
|
|
// const stampAny = compose<any>(); // $ExpectType Stamp<any>
|
|
// stampAny(); // $ExpectType any
|
|
const stampBigint = compose<bigint>(); // $ExpectType never
|
|
const stampBoolean = compose<boolean>(); // $ExpectType never
|
|
const stampNull = compose<null>(); // $ExpectType never
|
|
const stampNumber = compose<number>(); // $ExpectType never
|
|
const stampString = compose<string>(); // $ExpectType never
|
|
const stampSymbol = compose<symbol>(); // $ExpectType never
|
|
const stampUndefined = compose<undefined>(); // $ExpectType never
|
|
const stampUnknown = compose<unknown>(); // $ExpectType Stamp<unknown>
|
|
stampUnknown(); // $ExpectType unknown
|
|
const stampNever = compose<never>(); // $ExpectType never
|
|
|
|
// Declare interface of objects created by stamps
|
|
interface Object0 {
|
|
action: () => void;
|
|
value: number;
|
|
}
|
|
|
|
interface Object1 {
|
|
reaction: () => void;
|
|
property: number;
|
|
}
|
|
|
|
const stampObject0 = compose<Object0>(); // $ExpectType Stamp<Object0>
|
|
stampObject0(); // $ExpectType Object0
|
|
|
|
const stampObject1 = compose<Object1>(); // $ExpectType Stamp<Object1>
|
|
stampObject1(); // $ExpectType Object1
|
|
|
|
// Define a typed ExtendedDescriptor and benefit its properly typed `this` in `methods`
|
|
const descriptor0: stampit.ExtendedDescriptor<Object0> = {
|
|
methods: {
|
|
logLocalThis() {
|
|
this; // $ExpectType Object0
|
|
},
|
|
myMembers: {},
|
|
dbConnString: "pgs://data.local",
|
|
MY_LIMIT: 100,
|
|
myRegExp: /foobar/g,
|
|
},
|
|
properties: {},
|
|
deepProperties: {},
|
|
propertyDescriptors: {},
|
|
staticProperties: {},
|
|
staticDeepProperties: {},
|
|
staticPropertyDescriptors: {},
|
|
initializers: [
|
|
function(options, context) {
|
|
this; // $ExpectType Object0
|
|
return context.instance;
|
|
}
|
|
],
|
|
composers: [
|
|
(parameters) => {
|
|
return parameters.stamp;
|
|
}
|
|
],
|
|
configuration: {},
|
|
deepConfiguration: {}
|
|
};
|
|
|
|
const stampDescriptor0 = compose<typeof descriptor0>(descriptor0); // $ExpectType Stamp<Object0>
|
|
stampDescriptor0(); // $ExpectType Object0
|
|
|
|
// check typed stamps... with untyped descriptor (`this` isn't typed in `methods`)
|
|
// inline type assertion is still possible though
|
|
const stampUntypedDescriptor0 = compose<Object0>(/* <stampit.ExtendedDescriptor<Object0>> */ {
|
|
methods: {
|
|
logLocalThis() {
|
|
this; // $ExpectType any
|
|
},
|
|
myMembers: {},
|
|
dbConnString: "pgs://data.local",
|
|
MY_LIMIT: 100,
|
|
myRegExp: /foobar/g,
|
|
},
|
|
} /* as stampit.ExtendedDescriptor<Object0> */);
|
|
stampUntypedDescriptor0; // $ExpectType Stamp<Object0>
|
|
stampUntypedDescriptor0(); // $ExpectType Object0
|
|
|
|
// Check a stamp's `.compose()` method
|
|
const stamp1 = stampObject0.compose<Object1>(); // $ExpectType Stamp<Object1>
|
|
stamp1(); // $ExpectType Object1
|
|
|
|
// Define an extended stamp.
|
|
// The type of created object cannot be changed afterward
|
|
// Lazy interface composition can be done using the `&` intersection operator
|
|
interface ExtendedStamp extends stampit.Stamp<Object0 & Object1> {
|
|
decompose: () => unknown;
|
|
}
|
|
|
|
// Invoke `.compose()` method with the type of the extended stamp
|
|
const extendedStamp0 = compose<ExtendedStamp>(); // $ExpectType ExtendedStamp
|
|
extendedStamp0(); // $ExpectType Object0 & Object1
|