419 lines
16 KiB
TypeScript
419 lines
16 KiB
TypeScript
declare module "godot" {
|
|
const IntegerType: unique symbol;
|
|
const FloatType: unique symbol;
|
|
/**
|
|
* Proxy objects are typically transparent by design, allowing a proxy to impersonate a type. However, GodotJS also
|
|
* makes use of proxies to wrap existing objects in order to provide a more convenient API. In such cases, it is
|
|
* convenient to be able to unwrap the object i.e. obtain access to the target object. In order to achieve this,
|
|
* GodotJS exposes a property with the key ProxyTarget. You can access this to, for example, obtain direct access
|
|
* to the original GDictionary wrapped via a call to .proxy(). Additionally, GodotJS uses this property internally
|
|
* to unwrap proxies, thus allowing you to pass a proxy wrapped GArray/GDictionary as an argument to any function
|
|
* expecting a GArray/GDictionary parameter.
|
|
*/
|
|
const ProxyTarget: unique symbol;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Callable/Callable<T>.
|
|
*/
|
|
type AnyCallable = Callable;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Signal/Signal<T>.
|
|
*/
|
|
type AnySignal = Signal;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Callable<T>.
|
|
*/
|
|
type Callable0<R = void> = Callable<() => R>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Callable<T>.
|
|
*/
|
|
type Callable1<T1, R = void> = Callable<(v1: T1) => R>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Callable<T>.
|
|
*/
|
|
type Callable2<T1, T2, R = void> = Callable<(v1: T1, v2: T2) => R>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Callable<T>.
|
|
*/
|
|
type Callable3<T1, T2, T3, R = void> = Callable<(v1: T1, v2: T2, v3: T3) => R>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Callable<T>.
|
|
*/
|
|
type Callable4<T1, T2, T3, T4, R = void> = Callable<(v1: T1, v2: T2, v3: T3, v4: T4) => R>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Callable<T>.
|
|
*/
|
|
type Callable5<T1, T2, T3, T4, T5, R = void> = Callable<(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) => R>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Signal<T>.
|
|
*/
|
|
type Signal0 = Signal<() => void>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Signal<T>.
|
|
*/
|
|
type Signal1<T1> = Signal<(v1: T1) => void>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Signal<T>.
|
|
*/
|
|
type Signal2<T1, T2> = Signal<(v1: T1, v2: T2) => void>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Signal<T>.
|
|
*/
|
|
type Signal3<T1, T2, T3> = Signal<(v1: T1, v2: T2, v3: T3) => void>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Signal<T>.
|
|
*/
|
|
type Signal4<T1, T2, T3, T4> = Signal<(v1: T1, v2: T2, v3: T3, v4: T4) => void>;
|
|
|
|
/**
|
|
* FOR BACKWARD COMPATIBILITY ONLY
|
|
* @deprecated [WARNING] Use Signal<T>.
|
|
*/
|
|
type Signal5<T1, T2, T3, T4, T5> = Signal<(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) => void>;
|
|
|
|
type ExtractValueKeys<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
|
|
type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N;
|
|
|
|
type UndefinedToNull<T> = T extends undefined ? null : T;
|
|
|
|
// A bit convoluted, but written this way to mitigate type definitions circularly depending on themselves.
|
|
type GodotNames<T> = "__godotNameMap" extends keyof T
|
|
? keyof T["__godotNameMap"] | Exclude<keyof T, T["__godotNameMap"][keyof T["__godotNameMap"]]>
|
|
: keyof T;
|
|
type ResolveGodotName<T, Name> = Name extends keyof T
|
|
? Name
|
|
: "__godotNameMap" extends keyof T
|
|
? Name extends keyof T["__godotNameMap"]
|
|
? T["__godotNameMap"][Name]
|
|
: never
|
|
: never;
|
|
type ResolveGodotNameValue<T, Name> = Name extends keyof T
|
|
? T[Name]
|
|
: "__godotNameMap" extends keyof T
|
|
? Name extends keyof T["__godotNameMap"]
|
|
? T["__godotNameMap"][Name] extends keyof T
|
|
? T[T["__godotNameMap"][Name]]
|
|
: never
|
|
: never
|
|
: never;
|
|
type ResolveGodotNameParameters<T, Name> = Name extends GodotDynamicDispatchName
|
|
? GAny[]
|
|
: ResolveGodotName<T, Name> extends keyof T
|
|
? T[ResolveGodotName<T, Name>] extends {
|
|
bivarianceHack(...args: infer P extends GAny[]): void | GAny;
|
|
}["bivarianceHack"]
|
|
? P
|
|
: never
|
|
: never;
|
|
type ResolveGodotReturnType<T, Name> = Name extends GodotDynamicDispatchName
|
|
? void | GAny
|
|
: ResolveGodotName<T, Name> extends keyof T
|
|
? T[ResolveGodotName<T, Name>] extends (...args: any[]) => infer R
|
|
? R
|
|
: never
|
|
: never;
|
|
|
|
/**
|
|
* Godot has many APIs that are a form of dynamic dispatch, i.e., they take the name of a function or property and
|
|
* then operate on the value matching the name. TypeScript is powerful enough to allow us to type these APIs.
|
|
* However, since these APIs can be used to call each other, the type checker can get hung up trying to infinitely
|
|
* recurse on these types. What follows is an interface with the built-in dynamic dispatch names. GodotJS' types
|
|
* will not recurse through methods matching these names. If you want to build your own dynamic dispatch APIs, you
|
|
* can use interface merging to insert additional method names.
|
|
*/
|
|
interface GodotDynamicDispatchNames {
|
|
call: "call";
|
|
callv: "callv";
|
|
call_deferred: "call_deferred";
|
|
add_do_method: "add_do_method";
|
|
add_undo_method: "add_undo_method";
|
|
}
|
|
|
|
type GodotDynamicDispatchName = GodotDynamicDispatchNames[keyof GodotDynamicDispatchNames];
|
|
|
|
/**
|
|
* This namespace and the values within do not exist at runtime. They're declared here, for internal use only, as a
|
|
* work-around for limitations of TypeScript's type system.
|
|
*/
|
|
namespace __PathMappableDummyKeys {}
|
|
|
|
type PathMappable<DummyKey extends symbol, Map extends PathMap = PathMap> = {
|
|
[K in DummyKey]: Map;
|
|
};
|
|
|
|
type PathMap<T = unknown> = Record<string, T>;
|
|
|
|
type StaticPath<
|
|
Map extends PathMap,
|
|
Permitted = any,
|
|
DefaultKey extends string = never,
|
|
DummyKey extends symbol = (typeof __PathMappableDummyKeys)[keyof typeof __PathMappableDummyKeys],
|
|
> = IfAny<
|
|
Map,
|
|
string,
|
|
| (ExtractValueKeys<Map, Permitted> & string)
|
|
| (DummyKey extends any
|
|
?
|
|
| (Map[DefaultKey] extends never
|
|
? never
|
|
: Map[DefaultKey] extends PathMappable<DummyKey, infer ChildMap>
|
|
? StaticPath<ChildMap, Permitted, DefaultKey>
|
|
: never)
|
|
| {
|
|
[K in Exclude<keyof Map, DefaultKey> & string]: Map[K] extends PathMappable<
|
|
DummyKey,
|
|
infer ChildMap
|
|
>
|
|
? `${K}/${StaticPath<ChildMap, Permitted, DefaultKey>}`
|
|
: never;
|
|
}[Exclude<keyof Map, DefaultKey> & string]
|
|
: never)
|
|
>;
|
|
|
|
type ResolvePath<
|
|
Map extends PathMap,
|
|
Path extends string,
|
|
Default,
|
|
Permitted,
|
|
DefaultKey extends string = never,
|
|
DummyKey extends symbol = (typeof __PathMappableDummyKeys)[keyof typeof __PathMappableDummyKeys],
|
|
> = IfAny<
|
|
Map,
|
|
Permitted,
|
|
DummyKey extends any
|
|
? Path extends keyof Map
|
|
? [Map[Path]] extends [Permitted]
|
|
? [undefined] extends [Map[Path]]
|
|
? null | Exclude<Map[Path], undefined>
|
|
: Map[Path]
|
|
: Default
|
|
: Path extends `${infer Key extends Exclude<keyof Map, DefaultKey> & string}/${infer SubPath}`
|
|
? Map[Key] extends PathMappable<DummyKey, infer ChildMap>
|
|
? ResolvePath<ChildMap, SubPath, Default, Permitted>
|
|
: Default
|
|
: Map[DefaultKey] extends PathMappable<DummyKey, infer ChildMap>
|
|
? ResolvePath<ChildMap, Path, Default, Permitted>
|
|
: never
|
|
: never
|
|
>;
|
|
|
|
type PathMapChild<Map extends NodePathMap, Permitted, Default> = IfAny<
|
|
Map,
|
|
Permitted,
|
|
Map[keyof Map] extends undefined | Permitted ? Exclude<Map[keyof Map], undefined> : Default
|
|
>;
|
|
|
|
type NodePathMap = PathMap<undefined | Node>;
|
|
type StaticNodePath<Map extends NodePathMap, Permitted = Node> = StaticPath<
|
|
Map,
|
|
Permitted,
|
|
never,
|
|
typeof __PathMappableDummyKeys.Node
|
|
>;
|
|
type ResolveNodePath<Map extends NodePathMap, Path extends string, Default = never, Permitted = Node> = ResolvePath<
|
|
Map,
|
|
Path,
|
|
Default,
|
|
Permitted,
|
|
never,
|
|
typeof __PathMappableDummyKeys.Node
|
|
>;
|
|
type ResolveNodePathMap<Map extends NodePathMap, Path extends string, Default = never> = Path extends keyof Map
|
|
? Map[Path] extends Node<infer ChildMap>
|
|
? ChildMap
|
|
: Default
|
|
: Path extends `${infer Key extends keyof Map & string}/${infer SubPath}`
|
|
? Map[Key] extends Node<infer ChildMap>
|
|
? ResolveNodePathMap<ChildMap, SubPath, Default>
|
|
: Default
|
|
: Default;
|
|
type NodePathMapChild<Map extends NodePathMap> = PathMapChild<Map, Node, Node>;
|
|
|
|
type AnimationMixerPathMap = PathMap<AnimationLibrary>;
|
|
type StaticAnimationMixerPath<Map extends AnimationMixerPathMap> = StaticPath<
|
|
Map,
|
|
Animation,
|
|
"",
|
|
(typeof __PathMappableDummyKeys)["AnimationLibrary" | "AnimationMixer"]
|
|
>;
|
|
type ResolveAnimationMixerPath<
|
|
Map extends AnimationMixerPathMap,
|
|
Path extends string,
|
|
Default = never,
|
|
> = ResolvePath<
|
|
Map,
|
|
Path,
|
|
Default,
|
|
Animation,
|
|
"",
|
|
(typeof __PathMappableDummyKeys)["AnimationLibrary" | "AnimationMixer"]
|
|
>;
|
|
|
|
type GArrayElement<T extends GAny | GAny[], I extends int64 = int64> = T extends any[] ? T[I] : T;
|
|
|
|
/**
|
|
* GArray elements are exposed with a subset of JavaScript's standard Array API. Array indexes are exposed as
|
|
* enumerable properties, thus if you want to perform more complex operations you can convert to a regular
|
|
* JavaScript array with [...g_array.proxy()].
|
|
*/
|
|
class GArrayProxy<T> {
|
|
[Symbol.iterator](): IteratorObject<GProxyValueWrap<T>>;
|
|
|
|
/**
|
|
* Gets the length of the array. This is a number one higher than the highest index in the array.
|
|
*/
|
|
get length(): number;
|
|
|
|
/**
|
|
* Performs the specified action for each element in an array.
|
|
* @param callback A function that accepts up to three arguments. forEach calls the callback function one time for each element in the array.
|
|
* @param thisArg An object to which the this keyword can refer in the callback function. If thisArg is omitted, undefined is used as the this value.
|
|
*/
|
|
forEach<S = GArrayProxy<T>>(
|
|
callback: (this: GArrayProxy<T>, value: GProxyValueWrap<T>, index: number) => void,
|
|
thisArg?: S,
|
|
): void;
|
|
|
|
/**
|
|
* Removes the last element from an array and returns it.
|
|
* If the array is empty, undefined is returned and the array is not modified.
|
|
*/
|
|
pop(): GProxyValueWrap<T> | undefined;
|
|
|
|
/**
|
|
* Appends new elements to the end of an array, and returns the new length of the array.
|
|
* @param item New element to add to the array.
|
|
* @param additionalItems Additional new elements to add to the array.
|
|
*/
|
|
push(item: T | GProxyValueWrap<T>, ...additionalItems: Array<T | GProxyValueWrap<T>>): number;
|
|
|
|
/**
|
|
* Returns the index of the first occurrence of a value in an array, or -1 if it is not present.
|
|
* @param searchElement The value to locate in the array.
|
|
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
|
|
*/
|
|
indexOf(searchElement: T | GProxyValueWrap<T>, fromIndex?: number): number;
|
|
|
|
/**
|
|
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
|
* @param searchElement The element to search for.
|
|
*/
|
|
includes(searchElement: T | GProxyValueWrap<T>): boolean;
|
|
|
|
toJSON(key?: any): any;
|
|
|
|
toString(): string;
|
|
|
|
[n: number]: T | GProxyValueWrap<T>; // More accurate get type blocked by https://github.com/microsoft/TypeScript/issues/43826
|
|
}
|
|
|
|
// Ideally this would be a class, but TS currently doesn't provide a way to type a class with mapped properties.
|
|
/**
|
|
* GObject entries are exposed as enumerable properties, so Object.keys(), GObject.entries() etc. will work.
|
|
*/
|
|
type GDictionaryProxy<T> = {
|
|
[K in keyof T]: T[K] | GProxyValueWrap<T[K]>; // More accurate get type blocked by https://github.com/microsoft/TypeScript/issues/43826
|
|
};
|
|
|
|
type GProxyValueWrap<V> =
|
|
V extends GArray<infer T>
|
|
? GArrayProxy<GArrayElement<T>>
|
|
: V extends GDictionary<infer T>
|
|
? GDictionaryProxy<T>
|
|
: V;
|
|
|
|
type GProxyValueUnwrap<V> = V extends GArrayProxy<infer E> ? E : V extends GDictionaryProxy<infer T> ? T : V;
|
|
|
|
type GWrappableValue = GAny | GWrappableValue[] | { [key: number | string]: GWrappableValue };
|
|
type GValueWrapUnchecked<V> = V extends any[]
|
|
? number extends V["length"]
|
|
? GArray<GValueWrapUnchecked<V[number]>>
|
|
: GArray<{ [I in keyof V]: GValueWrapUnchecked<V[I]> }>
|
|
: V extends GAny
|
|
? V
|
|
: GDictionary<{ [K in keyof V]: GValueWrapUnchecked<V[K]> }>;
|
|
type GValueWrap<V> = [keyof V] extends [never]
|
|
? GDictionary<{}>
|
|
: [V] extends [GWrappableValue]
|
|
? GValueWrapUnchecked<V>
|
|
: never;
|
|
|
|
type GValueUnwrap<V> =
|
|
V extends GArray<infer T>
|
|
? T extends any[]
|
|
? { [I in keyof T]: GValueUnwrap<T[I]> }
|
|
: Array<GValueUnwrap<T>>
|
|
: V extends GDictionary<infer T>
|
|
? { [K in keyof T]: GValueUnwrap<T[K]> }
|
|
: V;
|
|
|
|
/**
|
|
* Semi-workaround for https://github.com/microsoft/TypeScript/issues/43826.
|
|
* @see GReadProxyValueWrap
|
|
*/
|
|
type GArrayReadProxy<T> = Omit<GArrayProxy<T>, "forEach"> & {
|
|
[Symbol.iterator](): IteratorObject<GReadProxyValueWrap<T>>;
|
|
forEach<S = GArrayReadProxy<T>>(
|
|
callback: (this: GArrayReadProxy<T>, value: GReadProxyValueWrap<T>, index: number) => void,
|
|
thisArg?: S,
|
|
): void;
|
|
[n: number]: GReadProxyValueWrap<T>;
|
|
};
|
|
|
|
/**
|
|
* Semi-workaround for https://github.com/microsoft/TypeScript/issues/43826.
|
|
* @see GReadProxyValueWrap
|
|
*/
|
|
type GDictionaryReadProxy<T> = {
|
|
[K in keyof T]: GReadProxyValueWrap<T[K]>;
|
|
};
|
|
|
|
// At runtime we only have the one kind of dictionary proxy and one kind of array proxy. The read interfaces have
|
|
// indexers typed correctly for access i.e. return proxied types. The non-read interfaces have indexers accurate for
|
|
// assignment and will accept both GArray/GDictionary and proxies. The read interfaces exist for convenience only,
|
|
// you can safely cast between the two interfaces types as desired.
|
|
type GReadProxyValueWrap<V> =
|
|
V extends GArray<infer E> ? GArrayReadProxy<E> : V extends GDictionary<infer T> ? GDictionaryReadProxy<T> : V;
|
|
|
|
interface PropertyInfo {
|
|
name: string;
|
|
type: Variant.Type;
|
|
class_name: string;
|
|
hint: PropertyHint;
|
|
hint_string: string;
|
|
usage: PropertyUsageFlags;
|
|
}
|
|
|
|
type BindRight<F extends Function, B extends any[]> = F extends (
|
|
this: infer T,
|
|
...args: [...infer A, ...B]
|
|
) => infer R
|
|
? (this: T, ...args: A) => R
|
|
: never;
|
|
}
|