///////// PROMISE /////////////
// As discussed in design meeting
// (1) we don't yet know of any cases where this fails
// (2) seems we need the four overloads of then to deal with success or failure being T
or Promise<T>
// (3) progress should be added
interface Promise<T> {
then<U>(success?: (x: T) => U, failure?: (x: any) => U): Promise<U>;
then<U>(success?: (x: T) => U, failure?: (x: any) => Promise<U>): Promise<U>;
then<U>(success?: (x: T) => Promise<U>, failure?: (x: any) => U): Promise<U>;
then<U>(success?: (x: T) => Promise<U>, failure?: (x: any) => Promise<U>): Promise<U>;
done(success?: (x: T) => any, failure? (x: any) => any): void;
}
var p = {
then(success?: (x: string) => any): any;
//done
}
///////// WINRT /////////////
// Basic:
// (1) just a handful of generic types
// (2) no generic methods
interface Windows.Foundation.Collections.IIterable<T> {
first(): Windows.Foundation.Collections.IIterator<T>
}
interface Windows.Foundation.Collections.IIterator<T> {
current: T;
hasCurrent: bool;
moveNext(): bool;
getMany(): T[];
}
interface Windows.Foundation.Collections.IVector<T> extends T[] {
size: number;
getAt(index: number): T;
indexOf(value: T): { index: number; returnValue: bool; };
getMany(startIndex: number): T[];
setAt(index: number, value: T): void;
insertAt(index: number, value: T): void;
removeAt(index: number): void;
removeAtEnd(): void;
clear(): void;
replaceAll(items: T[]): void;
}
interface Windows.Foundation.Collections.IMapView<K,V> {
size: number;
lookup(key: K): V;
hasKey(key: K): bool;
}
interface Windows.Foundation.Collections.IMap<K,V> {
size: number;
lookup(key: K): V;
hasKey(key: K): bool;
getView(): Windows.Foundation.Collections.IMapView<K,V>;
insert(key: K, value: V): bool;
remove(key: K): void;
clear(): void;
}
///////// ES6 Iterators /////////////
interface Iterator<T> {
next(): T;
}
interface Iterable<T> {
iterator(): Iterator<T>;
}
// This guy is hard
interface Generator<T> extends Iterator<any> {
send(x: any): any;
}
var f: () => Generator<string> = function *() {
var data = yield $.ajax(url);
$('#result').html(data);
var status = $('#status').html('Download complete.');
yield status.fadeIn().promise();
yield sleep(2000);
status.fadeOut();
return "hello";
}
var p: Promise<string> = spawn(f);
///////// KNOCKOUT /////////////
// (1) Generic "Observable" interface the central object of KnockOut
// (2) Nice interaction of generics and interface call signatures
// (3) Interesting need for 'generic this' for chaining of sets
declare module ko {
export interface Observable<T> {
(): T;
(value: T): void;
<O>(this: O, value: T): O; // Is this legit?
subscribe((newValue: T) => void ): {
dispose(): void
};
}
export function observable<T>(value: T): Observable<T>;
export function applyBindings(viewModel: any): void;
export function computed<T>(() => T, owner: any): Observable<T>;
export function computed<T>({ read: () => T; write?: (value: T) => void; owner?: any}): Observable<T>;
export function isComputed(o: any): bool;
export function isObservable(o: any): bool;
export function observable(o: any): bool;
}
var o = {
x: ko.observable("hello"),
y: ko.observable(5),
z: ko.computed(function() {
return this.x + this.y;
})
}
o.x("goodbye").y(6);
///////// UNDERSCORE /////////////
// Looks to be fairly standard LINQ-like library from the generics standpoint
// (1) Iteration over both arrays and objects (ordered string keyd dictionaries)
// (2) Not yet modelled below - API allows chained mode _([1,2,3]).map(f).filter(g)
_.each({a: 1, b: 4}, function(n) { return n + 1; });
// Note:
interface Underscore {
each<T>(
list: T[],
iterator: (element: T, index: number, list: T[]) => any,
context?: any): void;
each<T>(
obj: {[x: string]: T},
iterator: (value: T, key: string, object: {[x: string]: T}) => any,
context?: any): void;
map<T, U>(
list: T[],
iterator: (element: T, index?: number, list?: T[]) => U,
context?: any): U[];
map<T, U>(
obj: {[x: string]: T},
iterator: (value: T, key?: string, object?: {[x: string]: T}) => U,
context?: any): U[];
//?
invoke(list: any[], methodName: string, ...arguments: any[]): void;
pluck<T,U>(list: T[], propertyName: string): U[];
max(list: number[]): number;
max<T>(
list: T[],
iterator: (element: T, index: number, list: T[]) => number,
context?: any): number;
groupBy<T>(
list: T[],
iterator: (element: T, index: number, list: T[]) => string,
context?: any): { [key: string]: T[]; };
}
_.groupBy([1,2,3, 19], function(x) { return x.toString()[0]; })
{"1": [1,19], "2": [2], "3": [3] }
(<number[]>_.pluck(["a","b","c"], "length")) => [1,1,1]
_.pluck<string, number>(["a","b","c"], "length") => [1,1,1]
Generics and constraints.
Without constraints, the generic version is less expressive than the non-generic version (and as such, less useful in .d.ts to check against interface contracts). To regain this expressivity, we need to allow for constraints. Constraints can be based on a type variable extending an interface.