Property 'find' does not exist on type 'number[]'
bcherny opened this issue ยท 22 comments
[1,2,3].find(_ => _ === 3) // Property 'find' does not exist on type 'number[]'
though the typing for find()
is declared here https://github.com/Microsoft/TypeScript/blob/d27d10ce2ff013d66ff73890726b06587bda18fa/lib/lib.es6.d.ts#L339.
is there an alternative way of declaring an array here?
rookie mistake. to anyone wondering this in the future, be sure to set the compiler target
to es6
in your tsconfig.
thanks, this is helpful!!
Thank you!!! Was driving me crazy in my Typescript Compiler
How did I not notice this simple solution? Thank you!
I don't get it. I don't want to compile to ES6, I am using nativescript and need to compile to ES5. does this mean I can't use the find method? seems like a simple thing to compile.
I don't get it. I don't want to compile to ES6, I am using nativescript and need to compile to ES5. does this mean I can't use the find method? seems like a simple thing to compile.
TypeScript only provides down-emits for syntactical language features, not functional shims/polyfills. If the only polyfill you need is Array.prototype.find
then you could do all this yourself by adapting the polyfill from MDN and then augmenting the global Array
interface:
interface Array<T> {
find(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): T | undefined;
}
There is also a lib
option : https://basarat.gitbooks.io/typescript/content/docs/types/lib.d.ts.html#lib-option ๐น
But, @basarat that will not magically provide the functionality, which someone could mis-interpret and think "oh, all I need to do is include the lib and the functionality will be magically there at runtime."
Hi Guys, sorry to be dense, I'm still confused. Isn't Array.prototype.find a part of the ES2015 specification? (http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.find) and isn't Typescript supposed to be a superset of ES2015?
And how come this typescript code compiles and works fine in my Nativescript app
const myDumbArray: any = [{name: 'bob'}, {name: 'sally'}]
const sally = myDumbArray.find(dumbItem => dumbItem.name==='sally');
console.log(`here is ${sally.name}`);
But this errors out (error TS2339: Property 'find' does not exist on type 'Person[]')
const myTypedArray: Person[] = [{name: 'bob'}, {name: 'sally'}]
const bob = myTypedArray.find(dumbItem => dumbItem.name==='bob');
console.log(`here is ${bob}`);
At best this is counter-intuitive.
Thinking about it a bit more... Is the first code snippet only working because the version of javascript running on my emulator (genymotion - android) just happens to support the find method?
@JavascriptMick depending on the runtime you're targeting, you might not have certain functions. If TypeScript hinted to you that you had find
, then you'd be angry that at runtime it didn't work. So you need to think about it and opt in before you just decide to use any ES2015 functionality.
In TypeScript 2.0, you can tell the compiler "I'm using the standard library that comes with ES2015" using "lib": ["es5", "es2015"]
and then you'll get the right behavior.
Hi, I'm using "target": "es2015"
(on Typescript 2.0.6.0) and I still get this error, isn't it supposed to work, without the need to specify the lib option?
Guys, so when I want to use target es5, so all my code will work in browsers and modules exactly will be bundled into one file (!) and not pretend they will work with 'import this from that' like es2016-2017 and modules already everywhere... How can I use es6 features and still bundle everything into one file for browser?
How can I use es6 features and still bundle everything into one file for browser?
depending on what you mean by features.
if you are talking about built-in libraries, like the OP, then all you need is --targe es5 --lib es6
for instance to get the declarations of built in APIs.
if you mean syntactic feature, i.e. you want your const
, lambda's, and classes to not be transformed into var
, function
expressions, and function closures, but not use modules, then use --target ES6 --module none
thanks bcherny u saved me a whole lot of stress
I'm so confused by this. How do I know what exactly I can use? For example, I use arrow functions, and const in typescript, which gets transpiled to regular functions and vars. But then I try to use .find and it doesn't get transpiled into code for the JS version I'm targeting.
It is relatively straight forward. TypeScript does syntactic transpilation, not functional polyfilling.
That means if you use something like an arrow function, that is a syntactic feature of the language, therefore it is transpiled. TypeScript will not take care of things like Promise
, Set
, Map
, WeakMap
, etc. because those are functional aspects of the language. TypeScript expects you to provide that functionality yourself, if you wish to and then you can configure the compiler, by adding libs, to know that you are either providing that functionality, or only running in an environment that provides that functionality.
Where the syntactic feature requires functional feature, this is where it gets a little bit challenging. Using async
/await
, TypeScript assumes that a global Promise
is available in the run-time environment, but it does not provide it. Also you can use --downlevelIteration
when targeting ES3/ES5 which assumes that there is a global Symbol.iterator
at runtime, which allows the use of for ... of
for iterables other than Arrays and strings.
That clears some things up. I feel like I learned that Santa is not real all over again, but at least now I know what to actually expect from typescript.
Thank you.
TypeScript does syntactic transpilation, not functional polyfilling.
TypeScript does syntactic transpilation, not functional polyfilling.
TypeScript does syntactic transpilation, not functional polyfilling.
I have this on repeat until it finally sinks in..
I ran into the same issue with find and had to go back and change .find to another method.
I am learning..
If anyone is using Visual Studio make sure that in the TypeScript Build section of your project properties, that the ECMAScript Version is also set to ECMAScript 6.
Thanks, it's helpful.
I just was solved this problem by adding 'es2015' option in lib.