@typedly/descriptor
v11.0.0
Published
A TypeScript type definitions package for property descriptor.
Maintainers
Readme
typedly/descriptor
A TypeScript type definitions package for property descriptor.
Table of contents
Installation
1. Install peer dependencies
npm install @typedly/callback --save-peer2. Install the package
npm install @typedly/descriptor --save-peerApi
import {
// Interface.
AccessorPropertyDescriptor,
AugmentedDescriptorAttributes,
CommonPropertyDescriptor,
DataPropertyDescriptor,
KeyedAccessorPropertyDescriptor,
PropertyDescriptorChain,
PropertyDescriptors,
WrappedPropertyDescriptor,
// Type.
AnyPropertyDescriptor,
AttributedPropertyDescriptor,
AugmentedPropertyDescriptor,
ObjectPropertyDescriptors,
StrictPropertyDescriptor,
ThisAccessorPropertyDescriptor,
} from '@typedly/descriptor';Example data
// user.test.ts
export interface User {
name: string;
age: number;
email: string;
isActive: boolean;
createdAt: Date;
roles: string[];
address?: {
street: string;
city: string;
zipCode: string;
country: string;
};
}
export class UserClass implements User {
name: string = '';
age: number = 0;
email: string = '';
isActive: boolean = false;
createdAt: Date = new Date();
roles: string[] = [];
address?: {
street: string;
city: string;
zipCode: string;
country: string;
} = undefined;
}Interfaces
AccessorPropertyDescriptor
Represents an accessor property descriptor with its unique optional get() and set() functions, used to define or modify properties with getter and setter functions of the V type.
import { AccessorPropertyDescriptor } from '@typedly/descriptor';
// Apply the descriptor to an object
const obj: Person = {
name: "Jane",
age: 30,
};
const example: AccessorPropertyDescriptor<
string, // type of value
true, // configurable
true // enumerable
> = {
configurable: true,
enumerable: true,
get() {
return "example";
},
set(value: string) {
console.log(`Setting value: ${value}`);
},
};CommonPropertyDescriptor
Common keys configurable of generic type variable C and enumerable of generic type variable E for accessor and data descriptor, picked from the default PropertyDescriptor.
import { CommonPropertyDescriptor } from '@typedly/descriptor';AugmentedDescriptorAttributes
The attributes for the AugmentedPropertyDescriptor type.
import { AugmentedDescriptorAttributes } from '@typedly/descriptor';
import { User } from './user.test';
// AugmentedDescriptorAttributes<User, "name", "_name", string>
const attributes: AugmentedDescriptorAttributes<User, 'name', '_name'> = {
configurable: true,
enumerable: true,
set(this: User, value: string): void {
(this as any)._name = value;
},
get(): string {
return (this as any)._name;
},
privateKey: '_name',
}DataPropertyDescriptor
Represents a data property descriptor, which describes the attributes of a property that holds a specific value.
import { DataPropertyDescriptor } from '@typedly/descriptor';KeyedAccessorPropertyDescriptor
The accessor property descriptor of the specified object O and key K.
import { KeyedAccessorPropertyDescriptor } from '@typedly/descriptor';PropertyDescriptorChain
The shape of the property descriptor chain to store related descriptors.
import { PropertyDescriptorChain } from '@typedly/descriptor';PropertyDescriptors
The shape of a property descriptors chain in the object.
import { PropertyDescriptors } from '@typedly/descriptor';WrappedPropertyDescriptor
The interface for wrapped property descriptor.
Note:
The generic parameterDis now constrained toWrappedPropertyDescriptor<O, K, V, A, N, C, E, any> | PropertyDescriptor, with the default set toWrappedPropertyDescriptor<O, K, V, A, N, C, E, any>.
Thedescriptorparameter in thesetandgetmethods is always aWrappedPropertyDescriptor.
ThepreviousDescriptorproperty is typically aWrappedPropertyDescriptor, except for the initial wrap, where it may be a plainPropertyDescriptor(to support chaining from a base data descriptor).
import { WrappedPropertyDescriptor } from '@typedly/descriptor';
import { User, userClass } from './user.test';
const example: WrappedPropertyDescriptor<User, 'name'> = {
configurable: true,
enumerable: true,
privateKey: Symbol('name'),
enabled: true,
active: { onGet: true, onSet: true },
onGet(this: User, key, value, previousValue, target) {
console.log(`Getting ${String(key)}: ${value}`);
return value;
},
onSet(this: User, value, previousValue, key, instance) {
console.log(`Setting ${String(key)}: ${value}`);
return value;
},
set(this: User, value, descriptor) {
if (!descriptor?.enabled) return; // Property is disabled; do nothing
if (descriptor?.active && descriptor?.onSet) {
descriptor.onSet.call(this, value, '', 'name', this);
} else {
descriptor.privateKey && (this[descriptor.privateKey as keyof User] = value);
}
}
};Explanation:
privateKey: Uses a symbol to store the property value privately.enabled: true: The property stores the value as normal.active: Controls whether theonGetandonSetcallbacks are active.onGet/onSet: Log property access and assignment.
You can use this descriptor with a property wrapper system to intercept and customize property behavior on your objects. The simple wrap property class is available in the package @typescript-package/wrap-property
Types
AnyPropertyDescriptor
Represents an intersection of an accessor descriptor and a data descriptor.
import { AnyPropertyDescriptor } from '@typedly/descriptor';AttributedPropertyDescriptor
The attributed property descriptor for attributes customization.
import { AttributedPropertyDescriptor } from '@typedly/descriptor';
import { userClass } from './user.test';
// AttributedPropertyDescriptor<User, "name", string>
const attributedDescriptor: AttributedPropertyDescriptor<typeof userClass, 'name', string> = {
configurable: true,
enumerable: true,
get(this: typeof userClass) {
return this.name;
},
set(this: typeof userClass, value: string) {
this.name = value;
},
};AugmentedPropertyDescriptor
The customizable property descriptor.
import { AugmentedPropertyDescriptor } from '@typedly/descriptor';
import { User, userClass } from './user.test';
// Create custom attributes.
interface CustomAttributes<
O,
K extends keyof O,
P extends PropertyKey,
V extends K extends keyof O ? O[K] : any = K extends keyof O ? O[K] : any,
> extends AugmentedDescriptorAttributes<O, K, P, V> {
'customAttribute'?: string;
}
// AugmentedPropertyDescriptor<UserClass, "name", "_name" | "_age">
const example: AugmentedPropertyDescriptor<
typeof userClass, // object
'name', // key
'_name' | '_age', // private key
string, // value
CustomAttributes<typeof userClass, 'name', '_name' | '_age', string>, // attributes
> = {
configurable: true,
enumerable: true,
privateKey: '_name',
enabled: true,
active: { onGet: true, onSet: true },
onGet(this: User, key, value, previousValue, target) {
console.log(`Getting ${String(key)}: ${value}`);
return value;
},
onSet(value, previousValue, key, instance) {
console.log(`Setting ${String(key)}: ${value}`);
return value;
},
set(value, descriptor) {
if (!descriptor?.enabled) return; // Property is disabled; do nothing
if (descriptor?.active && descriptor?.onSet) {
descriptor.onSet.call(this, value, '', 'name', this);
} else {
// Assign only if privateKey is a string and matches a key of User
if (typeof descriptor.privateKey === 'string' && descriptor.privateKey in this) {
descriptor.privateKey === '_name' && (this[descriptor.privateKey] = value);
}
}
},
'customAttribute': 'This is a custom attribute',
};ObjectPropertyDescriptors
Represents a mapping of an object's properties to their respective property descriptors.
import { ObjectPropertyDescriptors } from '@typedly/descriptor';StrictPropertyDescriptor
Represents a union of an accessor descriptor and a data descriptor.
import { StrictPropertyDescriptor } from '@typedly/descriptor';ThisAccessorPropertyDescriptor
Represents the AccessorPropertyDescriptor interface as a type cause of ease of use this of an O type in the get() and set() methods.
import { ThisAccessorPropertyDescriptor } from '@typedly/descriptor';Contributing
Your contributions are valued! If you'd like to contribute, please feel free to submit a pull request. Help is always appreciated.
Support
If you find this package useful and would like to support its and general development, you can contribute through one of the following payment methods. Your support helps maintain the packages and continue adding new.
Support via:
or via Trust Wallet
Thanks for your support!
Code of Conduct
By participating in this project, you agree to follow Code of Conduct.
GIT
Commit
Versioning
Given a version number MAJOR.MINOR.PATCH, increment the:
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards-compatible manner, and
- PATCH version when you make backwards-compatible bug fixes.
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
FAQ How should I deal with revisions in the 0.y.z initial development phase?
The simplest thing to do is start your initial development release at 0.1.0 and then increment the minor version for each subsequent release.
How do I know when to release 1.0.0?
If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backwards compatibility, you should probably already be 1.0.0.
License
MIT © typedly (license)
Related packages
- @typescript-package/chain-descriptor: A TypeScript library for chain property descriptor.
- @typescript-package/controlled-descriptor: A TypeScript library for controlled property descriptor.
- @typescript-package/controller: A TypeScript package with for various kind of controllers.
- @typescript-package/descriptor-chain: A TypeScript library for property descriptor chain.
- @typescript-package/descriptor: A TypeScript library for property descriptor.
- @typescript-package/descriptors: A TypeScript library for property descriptors.
- @typescript-package/property: A TypeScript package with features to handle object properties.
- @typescript-package/wrap-descriptor: A TypeScript package for wrapping object descriptors.
- @typescript-package/wrap-property: A TypeScript package for wrapping object properties.
- @typescript-package/wrapped-descriptor: A lightweight TypeScript library for wrapped property descriptor.
- @xtypescript/property - A comprehensive, reactive TypeScript library for precise and extensible object property control.
