[ember] all computed property descriptors are also PropertyDecorators (#35114)

This commit is contained in:
Dan Freeman
2019-05-03 10:05:00 -07:00
committed by Wesley Wigham
parent f2daacd88c
commit 14db1e4e2c
6 changed files with 81 additions and 44 deletions
+2 -2
View File
@@ -31,10 +31,10 @@ export interface ControllerMixin extends ActionHandler {
export const ControllerMixin: Mixin<ControllerMixin>;
// tslint:disable-next-line:no-empty-interface
export default class Controller extends EmberObject.extend(ControllerMixin) {}
export function inject(): ComputedProperty<Controller> & PropertyDecorator;
export function inject(): ComputedProperty<Controller>;
export function inject<K extends keyof Registry>(
name: K
): ComputedProperty<Registry[K]> & PropertyDecorator;
): ComputedProperty<Registry[K]>;
export function inject(target: object, propertyKey: string | symbol): void;
// A type registry for Ember `Controller`s. Meant to be declaration-merged
+19 -2
View File
@@ -18,6 +18,23 @@ export type ExtractPropertyNamesOfType<T, S> = {
export type Fix<T> = { [K in keyof T]: T[K] };
/**
* Used to capture type information about a computed property, both
* the type of its value and (if it differs) the type its setter expects
* to receive.
*
* Note that this is intentionally a `class` and not a `type` or
* `interface` so that we can sneak in private fields that capture
* type info for the computed property without impacting the
* user-visible type.
*/
export class ComputedPropertyMarker<Get, Set = Get> {
// Necessary in order to avoid losing type information
// see: https://github.com/typed-ember/ember-cli-typescript/issues/246#issuecomment-414812013
private ______getType: Get;
private ______setType: Set;
}
/**
* Used to infer the type of ember classes of type `T`.
*
@@ -56,7 +73,7 @@ export type MixinOrLiteral<T, Base> = Mixin<T, Base> | T;
/**
* Deconstructs computed properties into the types which would be returned by `.get()`.
*/
export type UnwrapComputedPropertyGetter<T> = T extends ComputedProperty<
export type UnwrapComputedPropertyGetter<T> = T extends ComputedPropertyMarker<
infer U,
any
>
@@ -66,7 +83,7 @@ export type UnwrapComputedPropertyGetters<T> = {
[P in keyof T]: UnwrapComputedPropertyGetter<T[P]>
};
export type UnwrapComputedPropertySetter<T> = T extends ComputedProperty<
export type UnwrapComputedPropertySetter<T> = T extends ComputedPropertyMarker<
any,
infer V
>
+40 -37
View File
@@ -1,4 +1,5 @@
import { computed } from "@ember/object";
import { ComputedPropertyMarker } from "./-private/types";
/**
* A computed property transforms an objects function into a property.
@@ -7,10 +8,6 @@ import { computed } from "@ember/object";
* This will force the cached result to be recomputed if the dependencies are modified.
*/
export default class ComputedProperty<Get, Set = Get> {
// Necessary in order to avoid losing type information
// see: https://github.com/typed-ember/ember-cli-typescript/issues/246#issuecomment-414812013
private ______getType: Get;
private ______setType: Set;
/**
* Call on a computed property to set it into non-cached mode. When in this
* mode the computed property will not automatically cache the return value.
@@ -36,6 +33,12 @@ export default class ComputedProperty<Get, Set = Get> {
meta(): {};
}
// Computed property definitions also act as property decorators, including those
// returned from "macros" in third-party code. We additionally include a marker
// interface that we use in `UnwrapComputedProperty{G,S}etters`.
export default interface ComputedProperty<Get, Set = Get>
extends PropertyDecorator, ComputedPropertyMarker<Get, Set> {}
/**
* Creates a new property that is an alias for another property
* on an object. Calls to `get` or `set` this property behave as
@@ -43,21 +46,21 @@ export default class ComputedProperty<Get, Set = Get> {
*/
export function alias(
dependentKey: string
): ComputedProperty<any> & PropertyDecorator;
): ComputedProperty<any>;
/**
* A computed property that performs a logical `and` on the
* original values for the provided dependent properties.
*/
export function and(
...dependentKeys: string[]
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property that converts the provided dependent property
* into a boolean value.
*/
export function bool(
dependentKey: string
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property that returns the array of values
@@ -65,7 +68,7 @@ export function bool(
*/
export function collect(
...dependentKeys: string[]
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* Creates a new property that is an alias for another property
@@ -76,14 +79,14 @@ export function collect(
export function deprecatingAlias(
dependentKey: string,
options: { id: string; until: string }
): ComputedProperty<any> & PropertyDecorator;
): ComputedProperty<any>;
/**
* @deprecated Missing deprecation options: https://emberjs.com/deprecations/v2.x/#toc_ember-debug-function-options
*/
export function deprecatingAlias(
dependentKey: string,
options?: { id?: string; until?: string }
): ComputedProperty<any> & PropertyDecorator;
): ComputedProperty<any>;
/**
* A computed property that returns true if the value of the dependent
@@ -91,7 +94,7 @@ export function deprecatingAlias(
*/
export function empty(
dependentKey: string
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property that returns true if the provided dependent property
* is equal to the given value.
@@ -99,7 +102,7 @@ export function empty(
export function equal(
dependentKey: string,
value: any
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* Expands `pattern`, invoking `callback` for each expansion.
*/
@@ -114,7 +117,7 @@ export function expandProperties(
export function filter(
dependentKey: string,
callback: (value: any, index: number, array: any[]) => boolean
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* Filters the array by the property and value
@@ -123,7 +126,7 @@ export function filterBy(
dependentKey: string,
propertyKey: string,
value?: any
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* A computed property that returns true if the provided dependent property
@@ -132,7 +135,7 @@ export function filterBy(
export function gt(
dependentKey: string,
value: number
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property that returns true if the provided dependent property
* is greater than or equal to the provided value.
@@ -140,7 +143,7 @@ export function gt(
export function gte(
dependentKey: string,
value: number
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property which returns a new array with all the elements
@@ -148,7 +151,7 @@ export function gte(
*/
export function intersect(
...propertyKeys: string[]
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* A computed property that returns true if the provided dependent property
@@ -157,7 +160,7 @@ export function intersect(
export function lt(
dependentKey: string,
value: number
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property that returns true if the provided dependent property
* is less than or equal to the provided value.
@@ -165,7 +168,7 @@ export function lt(
export function lte(
dependentKey: string,
value: number
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* Returns an array mapped via the callback
@@ -173,7 +176,7 @@ export function lte(
export function map<U>(
dependentKey: string,
callback: (value: any, index: number, array: any[]) => U
): ComputedProperty<U[]> & PropertyDecorator;
): ComputedProperty<U[]>;
/**
* Returns an array mapped to the specified key.
@@ -181,7 +184,7 @@ export function map<U>(
export function mapBy(
dependentKey: string,
propertyKey: string
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* A computed property which matches the original value for the
@@ -191,7 +194,7 @@ export function mapBy(
export function match(
dependentKey: string,
regexp: RegExp
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property that calculates the maximum value in the
@@ -200,7 +203,7 @@ export function match(
*/
export function max(
dependentKey: string
): ComputedProperty<number> & PropertyDecorator;
): ComputedProperty<number>;
/**
* A computed property that calculates the minimum value in the
@@ -209,7 +212,7 @@ export function max(
*/
export function min(
dependentKey: string
): ComputedProperty<number> & PropertyDecorator;
): ComputedProperty<number>;
/**
* A computed property that returns true if the value of the dependent
@@ -218,21 +221,21 @@ export function min(
*/
export function none(
dependentKey: string
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property that returns the inverse boolean value
* of the original value for the dependent property.
*/
export function not(
dependentKey: string
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* A computed property that returns true if the value of the dependent
* property is NOT null, an empty string, empty array, or empty function.
*/
export function notEmpty(
dependentKey: string
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* Where `computed.alias` aliases `get` and `set`, and allows for bidirectional
* data flow, `computed.oneWay` only provides an aliased `get`. The `set` will
@@ -242,14 +245,14 @@ export function notEmpty(
*/
export function oneWay(
dependentKey: string
): ComputedProperty<any> & PropertyDecorator;
): ComputedProperty<any>;
/**
* A computed property which performs a logical `or` on the
* original values for the provided dependent properties.
*/
export function or(
...dependentKeys: string[]
): ComputedProperty<boolean> & PropertyDecorator;
): ComputedProperty<boolean>;
/**
* Where `computed.oneWay` provides oneWay bindings, `computed.readOnly` provides
* a readOnly one way binding. Very often when using `computed.oneWay` one does
@@ -257,14 +260,14 @@ export function or(
*/
export function readOnly(
dependentKey: string
): ComputedProperty<any> & PropertyDecorator;
): ComputedProperty<any>;
/**
* This is a more semantically meaningful alias of `computed.oneWay`,
* whose name is somewhat ambiguous as to which direction the data flows.
*/
export function reads(
dependentKey: string
): ComputedProperty<any> & PropertyDecorator;
): ComputedProperty<any>;
/**
* A computed property which returns a new array with all the
@@ -274,7 +277,7 @@ export function reads(
export function setDiff(
setAProperty: string,
setBProperty: string
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* A computed property which returns a new array with all the
@@ -284,14 +287,14 @@ export function setDiff(
export function sort(
itemsKey: string,
sortDefinition: string | ((itemA: any, itemB: any) => number)
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* A computed property that returns the sum of the values
* in the dependent array.
*/
export function sum(
dependentKey: string
): ComputedProperty<number> & PropertyDecorator;
): ComputedProperty<number>;
/**
* A computed property which returns a new array with all the unique
@@ -299,7 +302,7 @@ export function sum(
*/
export function uniq(
propertyKey: string
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* A computed property which returns a new array with all the unique
@@ -307,7 +310,7 @@ export function uniq(
*/
export function union(
...propertyKeys: string[]
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
/**
* A computed property which returns a new array with all the unique
@@ -316,4 +319,4 @@ export function union(
export function uniqBy(
dependentKey: string,
propertyKey: string
): ComputedProperty<any[]> & PropertyDecorator;
): ComputedProperty<any[]>;
+1 -1
View File
@@ -22,7 +22,7 @@ import ComputedProperty, * as ComputedNamespace from "@ember/object/computed";
* see the documentation for each of these.
*/
export default class EmberObject extends CoreObject.extend(Observable) {}
declare function computed(...deps: string[]): (target: object, propertyKey: string) => void;
declare function computed(...deps: string[]): MethodDecorator;
declare function computed<T>(
cb: ComputedPropertyCallback<T>
): ComputedProperty<T>;
+17
View File
@@ -34,6 +34,12 @@ import {
uniqBy
} from "@ember/object/computed";
function customMacro(message: string) {
return computed(() => {
return [message, message];
});
}
// Native class syntax
class Foo extends EmberObject {
firstName: string;
@@ -47,6 +53,17 @@ class Foo extends EmberObject {
return `${this.firstName} ${this.lastName}`;
}
@computed("firstName", "lastName") // $ExpectError
badFullName: string;
@computed("fullName", function(this: Foo) {
return this.fullName.toUpperCase();
})
bigFullName: string;
@customMacro('hi')
hiTwice: string[];
@action
foo() {}
}
+2 -2
View File
@@ -12,9 +12,9 @@ export default class Service extends EmberObject {}
* Creates a property that lazily looks up a service in the container. There
* are no restrictions as to what objects a service can be injected into.
*/
export function inject(): PropertyDecorator & ComputedProperty<Service>; // @inject() foo, foo: inject()
export function inject(): ComputedProperty<Service>; // @inject() foo, foo: inject()
export function inject(target: object, propertyKey: string | symbol): void; // @inject foo
export function inject<K extends keyof Registry>(name: K): PropertyDecorator & ComputedProperty<Registry[K]>; // @inject('store') foo @inject() foo
export function inject<K extends keyof Registry>(name: K): ComputedProperty<Registry[K]>; // @inject('store') foo @inject() foo
// A type registry for Ember `Service`s. Meant to be declaration-merged so
// string lookups resolve to the correct type.