-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20180 from emberjs/preview-types
[FEATURE] Introduce preview types
- Loading branch information
Showing
188 changed files
with
11,647 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,5 @@ node-tests/fixtures/**/*.js | |
dist/ | ||
tmp/ | ||
smoke-tests/ | ||
types/ | ||
type-tests/preview |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
type-tests/preview/@ember/application-test/application-instance.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import ApplicationInstance from '@ember/application/instance'; | ||
|
||
declare function hbs(strings: TemplateStringsArray): object; | ||
|
||
const appInstance = ApplicationInstance.create(); | ||
appInstance.register('some:injection', class Foo {}); | ||
|
||
appInstance.register('some:injection', class Foo {}, { | ||
singleton: true, | ||
}); | ||
|
||
appInstance.register('some:injection', class Foo {}, { | ||
instantiate: false, | ||
}); | ||
|
||
appInstance.register('templates:foo/bar', hbs`<h1>Hello World</h1>`); | ||
appInstance.register('templates:foo/bar', hbs`<h1>Hello World</h1>`, { | ||
singleton: true, | ||
}); | ||
appInstance.register('templates:foo/bar', hbs`<h1>Hello World</h1>`, { | ||
instantiate: true, | ||
}); | ||
appInstance.register('templates:foo/bar', hbs`<h1>Hello World</h1>`, { | ||
singleton: true, | ||
instantiate: true, | ||
}); | ||
appInstance.register('templates:foo/bar', hbs`<h1>Hello World</h1>`, { | ||
// @ts-expect-error | ||
singleton: 'true', | ||
instantiate: true, | ||
}); | ||
|
||
appInstance.register('some:injection', class Foo {}, { | ||
singleton: false, | ||
instantiate: true, | ||
}); | ||
|
||
appInstance.factoryFor('router:main'); | ||
appInstance.lookup('route:basic'); | ||
|
||
appInstance.boot(); | ||
|
||
(async () => { | ||
await appInstance.boot(); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import Application from '@ember/application'; | ||
import ApplicationInstance from '@ember/application/instance'; | ||
import EmberObject from '@ember/object'; | ||
import { expectTypeOf } from 'expect-type'; | ||
|
||
const BaseApp = Application.extend({ | ||
modulePrefix: 'my-app', | ||
}); | ||
|
||
class Obj extends EmberObject.extend({ foo: 'bar' }) {} | ||
|
||
BaseApp.initializer({ | ||
name: 'my-initializer', | ||
initialize(app) { | ||
app.register('foo:bar', Obj); | ||
}, | ||
}); | ||
|
||
BaseApp.instanceInitializer({ | ||
name: 'my-instance-initializer', | ||
initialize(app) { | ||
(app.lookup('foo:bar') as Obj).get('foo'); | ||
}, | ||
}); | ||
|
||
const App1 = BaseApp.create({ | ||
rootElement: '#app-one', | ||
customEvents: { | ||
paste: 'paste', | ||
}, | ||
}); | ||
|
||
const App2 = BaseApp.create({ | ||
rootElement: '#app-two', | ||
customEvents: { | ||
mouseenter: null, | ||
mouseleave: null, | ||
}, | ||
}); | ||
|
||
const App3 = BaseApp.create(); | ||
|
||
expectTypeOf(App3.buildInstance()).toEqualTypeOf<ApplicationInstance>(); | ||
expectTypeOf(App3.buildInstance({ foo: 'bar' })).toEqualTypeOf<ApplicationInstance>(); |
17 changes: 17 additions & 0 deletions
17
type-tests/preview/@ember/application-test/deprecations.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { deprecate, deprecateFunc } from '@ember/application/deprecations'; | ||
|
||
deprecate('this is no longer advised', false, { | ||
id: 'no-longer-advised', | ||
until: 'v4.0', | ||
}); | ||
deprecate('this is no longer advised', false, { | ||
id: 'no-longer-advised', | ||
until: 'v4.0', | ||
url: 'https://emberjs.com', | ||
}); | ||
// @ts-expect-error | ||
deprecate('this is no longer advised', false); | ||
|
||
// @ts-expect-error | ||
deprecateFunc('this is no longer advised', () => {}); | ||
deprecateFunc('this is no longer advised', { id: 'no-longer-do-this', until: 'v4.0' }, () => {}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { getOwner, setOwner } from '@ember/application'; | ||
import EngineInstance from '@ember/engine/instance'; | ||
import Owner from '@ember/owner'; | ||
import ApplicationInstance from '@ember/application/instance'; | ||
import Service from '@ember/service'; | ||
import { expectTypeOf } from 'expect-type'; | ||
|
||
expectTypeOf(getOwner({})).toEqualTypeOf<Owner | undefined>(); | ||
|
||
// Confirm that random subclasses work as expected. | ||
declare class MyService extends Service { | ||
withStuff: true; | ||
} | ||
declare let myService: MyService; | ||
expectTypeOf(getOwner(myService)).toEqualTypeOf<Owner>(); | ||
|
||
// @ts-expect-error | ||
getOwner(); | ||
|
||
declare let baseOwner: Owner; | ||
expectTypeOf(setOwner({}, baseOwner)).toBeVoid(); | ||
|
||
declare let engine: EngineInstance; | ||
expectTypeOf(setOwner({}, engine)).toBeVoid(); | ||
|
||
declare let application: ApplicationInstance; | ||
expectTypeOf(setOwner({}, application)).toBeVoid(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import ArrayProxy from '@ember/array/proxy'; | ||
import EmberArray, { A } from '@ember/array'; | ||
import EmberObject from '@ember/object'; | ||
import { expectTypeOf } from 'expect-type'; | ||
|
||
const pets = ['dog', 'cat', 'fish']; | ||
const proxy = ArrayProxy.create({ content: A(pets) }); | ||
|
||
proxy.get('firstObject'); // 'dog' | ||
proxy.set('content', A(['amoeba', 'paramecium'])); | ||
proxy.get('firstObject'); // 'amoeba' | ||
|
||
const overridden = ArrayProxy.create({ | ||
content: A(pets), | ||
objectAtContent(this: ArrayProxy<string>, idx: number): string | undefined { | ||
// NOTE: cast is necessary because `this` is not managed correctly in the | ||
// `.create()` body anymore. | ||
return (this.get('content') as EmberArray<string>).objectAt(idx)?.toUpperCase(); | ||
}, | ||
}); | ||
|
||
overridden.get('firstObject'); // 'DOG' | ||
|
||
class MyNewProxy<T> extends ArrayProxy<T> { | ||
isNew = true; | ||
} | ||
|
||
const x = MyNewProxy.create({ content: A([1, 2, 3]) }) as MyNewProxy<number>; | ||
expectTypeOf(x.get('firstObject')).toEqualTypeOf<number | undefined>(); | ||
expectTypeOf(x.isNew).toBeBoolean(); | ||
|
||
// Custom EmberArray | ||
interface MyArray<T> extends EmberObject, EmberArray<T> {} | ||
class MyArray<T> extends EmberObject.extend(EmberArray) { | ||
constructor(content: ArrayLike<T>) { | ||
super(); | ||
this._content = content; | ||
} | ||
|
||
_content: ArrayLike<T>; | ||
|
||
get length() { | ||
return this._content.length; | ||
} | ||
|
||
objectAt(idx: number) { | ||
return this._content[idx]; | ||
} | ||
} | ||
|
||
const customArrayProxy = ArrayProxy.create({ content: new MyArray(pets) }); | ||
customArrayProxy.get('firstObject'); // 'dog' | ||
|
||
// Vanilla array | ||
const vanillaArrayProxy = ArrayProxy.create({ content: pets }); | ||
vanillaArrayProxy.get('firstObject'); // 'dog' | ||
|
||
// Nested ArrayProxy | ||
const nestedArrayProxy = ArrayProxy.create({ content: proxy }); | ||
nestedArrayProxy.get('firstObject'); // 'amoeba' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import EmberObject from '@ember/object'; | ||
import type Array from '@ember/array'; | ||
import { A } from '@ember/array'; | ||
import type MutableArray from '@ember/array/mutable'; | ||
import { expectTypeOf } from 'expect-type'; | ||
|
||
class Person extends EmberObject { | ||
name = ''; | ||
isHappy = false; | ||
} | ||
|
||
const people = A([ | ||
Person.create({ name: 'Yehuda', isHappy: true }), | ||
Person.create({ name: 'Majd', isHappy: false }), | ||
]); | ||
|
||
expectTypeOf(people.get('length')).toBeNumber(); | ||
expectTypeOf(people.get('lastObject')).toEqualTypeOf<Person | undefined>(); | ||
expectTypeOf(people.get('firstObject')).toEqualTypeOf<Person | undefined>(); | ||
expectTypeOf(people.isAny('isHappy')).toBeBoolean(); | ||
expectTypeOf(people.isAny('isHappy', false)).toBeBoolean(); | ||
// @ts-expect-error -- string != boolean | ||
people.isAny('isHappy', 'false'); | ||
|
||
expectTypeOf(people.objectAt(0)).toEqualTypeOf<Person | undefined>(); | ||
expectTypeOf(people.objectsAt([1, 2, 3])).toEqualTypeOf<Array<Person | undefined>>(); | ||
|
||
expectTypeOf(people.filterBy('isHappy')).toMatchTypeOf<Person[]>(); | ||
expectTypeOf(people.filterBy('isHappy')).toMatchTypeOf<MutableArray<Person>>(); | ||
expectTypeOf(people.rejectBy('isHappy')).toMatchTypeOf<Person[]>(); | ||
expectTypeOf(people.rejectBy('isHappy')).toMatchTypeOf<MutableArray<Person>>(); | ||
expectTypeOf(people.filter((person) => person.get('name') === 'Yehuda')).toMatchTypeOf<Person[]>(); | ||
expectTypeOf(people.filter((person) => person.get('name') === 'Yehuda')).toMatchTypeOf< | ||
MutableArray<Person> | ||
>(); | ||
|
||
expectTypeOf(people.get('[]')).toEqualTypeOf<typeof people>(); | ||
expectTypeOf(people.get('[]').get('firstObject')).toEqualTypeOf<Person | undefined>(); | ||
|
||
expectTypeOf(people.mapBy('isHappy')).toMatchTypeOf<boolean[]>(); | ||
expectTypeOf(people.mapBy('name.length')).toMatchTypeOf<unknown[]>(); | ||
|
||
const last = people.get('lastObject'); | ||
expectTypeOf(last).toEqualTypeOf<Person | undefined>(); | ||
if (last) { | ||
expectTypeOf(last.get('name')).toBeString(); | ||
} | ||
|
||
const first = people.get('lastObject'); | ||
if (first) { | ||
expectTypeOf(first.get('isHappy')).toBeBoolean(); | ||
} | ||
|
||
const letters = A(['a', 'b', 'c']); | ||
const codes = letters.map((item, index, array) => { | ||
expectTypeOf(item).toBeString(); | ||
expectTypeOf(index).toBeNumber(); | ||
expectTypeOf(array).toMatchTypeOf<string[]>(); | ||
return item.charCodeAt(0); | ||
}); | ||
expectTypeOf(codes).toMatchTypeOf<number[]>(); | ||
|
||
const value = '1,2,3'; | ||
const filters = A(value.split(',')); | ||
filters.push('4'); | ||
filters.sort(); | ||
|
||
const multiSortArr = A([ | ||
{ k: 'a', v: 'z' }, | ||
{ k: 'a', v: 'y' }, | ||
{ k: 'b', v: 'c' }, | ||
]); | ||
multiSortArr.sortBy('k', 'v'); |
Oops, something went wrong.