mirror of
https://github.com/konvajs/konva.git
synced 2025-11-08 10:34:46 +08:00
Better types inferences for Rect attributes
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -20,6 +20,7 @@ types
|
||||
out.png
|
||||
cmj
|
||||
.test-temp
|
||||
.history
|
||||
|
||||
# Numerous always-ignore extensions
|
||||
*.diff
|
||||
|
||||
@@ -32,7 +32,8 @@ export interface ContainerConfig extends NodeConfig {
|
||||
*/
|
||||
export abstract class Container<
|
||||
ChildType extends Node = Node,
|
||||
> extends Node<ContainerConfig> {
|
||||
Config extends ContainerConfig = ContainerConfig
|
||||
> extends Node<Config> {
|
||||
children: Array<ChildType> = [];
|
||||
|
||||
/**
|
||||
|
||||
29
src/Node.ts
29
src/Node.ts
@@ -10,7 +10,7 @@ import type { Layer } from './Layer.ts';
|
||||
import type { Shape } from './Shape.ts';
|
||||
import type { Stage } from './Stage.ts';
|
||||
import type { GetSet, IRect, Vector2d } from './types.ts';
|
||||
import { Transform, Util } from './Util.ts';
|
||||
import { Transform, Util, type AnyString } from './Util.ts';
|
||||
import {
|
||||
getBooleanValidator,
|
||||
getNumberValidator,
|
||||
@@ -134,9 +134,8 @@ type globalCompositeOperationType =
|
||||
| 'color'
|
||||
| 'luminosity';
|
||||
|
||||
export interface NodeConfig {
|
||||
// allow any custom attribute
|
||||
[index: string]: any;
|
||||
// allow any custom attribute
|
||||
export type NodeConfig<Props extends Record<string, any> = {}> = Props & {
|
||||
x?: number;
|
||||
y?: number;
|
||||
width?: number;
|
||||
@@ -1015,13 +1014,13 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @example
|
||||
* var x = node.getAttr('x');
|
||||
*/
|
||||
getAttr<T>(attr: string) {
|
||||
const method = 'get' + Util._capitalize(attr);
|
||||
getAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(attr: K): K extends keyof AttrConfig ? AttrConfig[K] : any {
|
||||
const method = 'get' + Util._capitalize(attr as string);
|
||||
if (Util._isFunction((this as any)[method])) {
|
||||
return (this as any)[method]();
|
||||
}
|
||||
// otherwise get directly
|
||||
return this.attrs[attr] as T | undefined;
|
||||
return this.attrs[attr];
|
||||
}
|
||||
/**
|
||||
* get ancestors
|
||||
@@ -1050,8 +1049,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @name Konva.Node#getAttrs
|
||||
* @returns {Object}
|
||||
*/
|
||||
getAttrs() {
|
||||
return (this.attrs || {}) as Config & Record<string, any>;
|
||||
getAttrs(): Config {
|
||||
return (this.attrs || {});
|
||||
}
|
||||
/**
|
||||
* set multiple attrs at once using an object literal
|
||||
@@ -1065,7 +1064,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* fill: 'red'
|
||||
* });
|
||||
*/
|
||||
setAttrs(config: any) {
|
||||
setAttrs(config?: Config) {
|
||||
this._batchTransformChanges(() => {
|
||||
let key, method;
|
||||
if (!config) {
|
||||
@@ -1624,7 +1623,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @returns {Object}
|
||||
*/
|
||||
toObject() {
|
||||
let attrs = this.getAttrs() as any,
|
||||
let attrs = this.getAttrs(),
|
||||
key,
|
||||
val,
|
||||
getter,
|
||||
@@ -2405,8 +2404,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
* @example
|
||||
* node.setAttr('x', 5);
|
||||
*/
|
||||
setAttr(attr: string, val) {
|
||||
const func = this[SET + Util._capitalize(attr)];
|
||||
setAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(attr: K, val: K extends keyof AttrConfig ? AttrConfig[K] : any) {
|
||||
const func = this[SET + Util._capitalize(attr as string)];
|
||||
|
||||
if (Util._isFunction(func)) {
|
||||
func.call(this, val);
|
||||
@@ -2422,7 +2421,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
drawNode?.batchDraw();
|
||||
}
|
||||
}
|
||||
_setAttr(key: string, val) {
|
||||
_setAttr<AttrConfig extends Config, K extends AnyString<keyof Config>>(key: K, val: K extends keyof AttrConfig ? AttrConfig[K] : any) {
|
||||
const oldVal = this.attrs[key];
|
||||
if (oldVal === val && !Util.isObject(val)) {
|
||||
return;
|
||||
@@ -2878,7 +2877,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
}
|
||||
|
||||
interface AnimTo extends NodeConfig {
|
||||
interface AnimTo extends NodeConfig<Record<string, any>> {
|
||||
onFinish?: Function;
|
||||
onUpdate?: Function;
|
||||
duration?: number;
|
||||
|
||||
@@ -26,7 +26,7 @@ export type ShapeConfigHandler<TTarget> = {
|
||||
export type LineJoin = 'round' | 'bevel' | 'miter';
|
||||
export type LineCap = 'butt' | 'round' | 'square';
|
||||
|
||||
export interface ShapeConfig extends NodeConfig {
|
||||
export type ShapeConfig<Props extends Record<string, any> = {}> = NodeConfig<Props> & {
|
||||
fill?: string | CanvasGradient;
|
||||
fillPatternImage?: HTMLImageElement;
|
||||
fillPatternX?: number;
|
||||
|
||||
@@ -154,7 +154,7 @@ export const stages: Stage[] = [];
|
||||
* });
|
||||
*/
|
||||
|
||||
export class Stage extends Container<Layer> {
|
||||
export class Stage extends Container<Layer, StageConfig> {
|
||||
content: HTMLDivElement;
|
||||
pointerPos: Vector2d | null;
|
||||
_pointerPositions: (Vector2d & { id?: number })[] = [];
|
||||
|
||||
@@ -151,6 +151,9 @@ class TweenEngine {
|
||||
}
|
||||
|
||||
export interface TweenConfig extends NodeConfig {
|
||||
easing?: typeof Easings[keyof typeof Easings];
|
||||
yoyo?: boolean;
|
||||
onReset?: Function;
|
||||
onFinish?: Function;
|
||||
onUpdate?: Function;
|
||||
duration?: number;
|
||||
@@ -419,7 +422,7 @@ export class Tween {
|
||||
// after tweening points of line we need to set original end
|
||||
const attrs = Tween.attrs[node._id][this._id];
|
||||
if (attrs.points && attrs.points.trueEnd) {
|
||||
node.setAttr('points', attrs.points.trueEnd);
|
||||
node.setAttr('points' as any, attrs.points.trueEnd);
|
||||
}
|
||||
|
||||
if (this.onFinish) {
|
||||
|
||||
@@ -1121,3 +1121,5 @@ export const Util = {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export type AnyString<T> = T | (string & {})
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { GetSet } from '../types.ts';
|
||||
import type { Context } from '../Context.ts';
|
||||
import { getNumberOrArrayOfNumbersValidator } from '../Validators.ts';
|
||||
|
||||
export interface RectConfig extends ShapeConfig {
|
||||
export type RectConfig<Props extends Record<string, any> = {}> = ShapeConfig<Props> & {
|
||||
cornerRadius?: number | number[];
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export interface RectConfig extends ShapeConfig {
|
||||
* strokeWidth: 5
|
||||
* });
|
||||
*/
|
||||
export class Rect extends Shape<RectConfig> {
|
||||
export class Rect<Props extends Record<string, any> = {}> extends Shape<RectConfig<Props>> {
|
||||
_sceneFunc(context: Context) {
|
||||
const cornerRadius = this.cornerRadius(),
|
||||
width = this.width(),
|
||||
|
||||
Reference in New Issue
Block a user