Package Exports
- linq-to-typescript
Readme
LINQ To TypeScript
- Implementation of LINQ for TypeScript
- Targets TypeScript 3.9.X and ES 2018
await from([bing, google, quackQuackGo])
.asParallel()
.selectAsync(downloadHtml)
.select(getTitle)
.toArray()Getting Started
npm i linq-to-typescripttsconfig.json
"compilerOptions": {
"target": "es2018",
"lib": [
"dom",
"es2018"
],
"importHelpers": true
}- The
strictTS option is recommended. - Library is dependent on tslib for async iteration polyfills.
Using the Library
With Wrappers
// 0. Import Module
import { from } from "linq-to-typescript"
// To Use With Wrappers
const evenNumbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9]).where((x) => x % 2 === 0).toArray()Without Wrappers
// 0. Import Module
import { initializeLinq, IEnumerable } from "linq-to-typescript"
// 1. Declare that the JS types implement the IEnumerable interface
declare global {
interface Array<T> extends IEnumerable<T> { }
interface Uint8Array extends IEnumerable<number> { }
interface Uint8ClampedArray extends IEnumerable<number> { }
interface Uint16Array extends IEnumerable<number> { }
interface Uint32Array extends IEnumerable<number> { }
interface Int8Array extends IEnumerable<number> { }
interface Int16Array extends IEnumerable<number> { }
interface Int32Array extends IEnumerable<number> { }
interface Float32Array extends IEnumerable<number> { }
interface Float64Array extends IEnumerable<number> { }
interface Map<K, V> extends IEnumerable<[K, V]> { }
interface Set<T> extends IEnumerable<T> { }
interface String extends IEnumerable<string> { }
}
// 2. Bind Linq Functions to Array and Map
initializeLinq()
// 3. Use without a wrapper type
const evenNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9].where((x) => x % 2 === 0).toArray()Examples
Please refer to EXAMPLES.md
API
LinqToTypeScript implements the functionality of the IEnumerable interface
- IEnumerable, IAsyncEnumerable, and IParallelEnumerable interfaces are based on,
- IEnumerable<T> Interface
- Some changes made due to conflics with existing method names
- Some changes made due to limitations of JavaScript
IEnumerable
- Inspired by LINQ API Surface
- Has Async methods that return
PromiseorIAsyncEnumerable - Implements
Iterable<T> - Use
fromto wrap your arrays
IAsyncEnumerable
- Inspired by LINQ API Surface
- Has Async methods that return
PromiseorIAsyncEnumerable - For asynchronous iteration
- Implements
AsyncIterable<T>interface - Use
fromAsyncto wrap your AsyncIterable type
IParallelEnumerable
- Inspired by LINQ API Surface
- Has Async methods that return
PromiseorIParallelEnumerable - For asynchronous iteration in parallel (where possible)
- Implements
AsyncIterable<T>interface - Use
fromParallelto create a parallel enumeration
Shared Instance Methods
| Method | Async* | Tests Coverage | Notes |
|---|---|---|---|
| aggregate | No | Sync | |
| all | Yes | Sync, Async | |
| any | Yes | Sync, Async | |
| average | Yes | Sync, Async | |
| concatenate | No | Sync | Equivalent to .Concat but renamed to avoid conflict with JS |
| contains | Yes | Sync, Async | |
| count | Yes | Sync, Async | |
| distinct | Yes | Sync, Async | |
| elementAt | No | Sync | |
| elementAtOrDefault | No | Sync | |
| except | Yes | Sync, Async | |
| first | Yes | Sync, Async | |
| firstOrDefault | Yes | Sync, Async | |
| each | Yes | Sync, Async | From List<T>.ForEach |
| groupBy | Yes | Sync, Async | |
| groupByWithSel | No | Sync | |
| intersect | Yes | Sync, Async | |
| joinByKey | No | Sync | |
| last | Yes | Sync, Async | |
| lastOrDefault | Yes | Sync, Async | |
| max | Yes | Sync, Async | |
| min | Yes | Sync, Async | |
| ofType | No | Sync | |
| orderBy | Yes | Sync, Async | |
| orderByDescending | Yes | Sync, Async | |
| reverse | No | Sync | |
| select | Yes | Sync, Async | |
| selectMany | Yes | Sync, Async | |
| sequenceEquals | Yes | Sync, Async | |
| single | Yes | Sync, Async | |
| singleOrDefault | Yes | Sync, Async | |
| skip | No | Sync | |
| skipWhile | Yes | Sync, Async | |
| sum | Yes | Sync, Async | |
| take | No | Sync | |
| takeWhile | Yes | Sync, Async | |
| toArray | No | Sync | |
| toMap | Yes | Sync, Async | Equivalent to ToDictionary |
| toSet | No | Sync | Equivalent to ToHashSet. No comparer overload for JS. |
| union | Yes | Sync | |
| where | Yes | Sync, Async | |
| zip | Yes | Sync, Async |
* Async methods take an async function
Static Methods
| Method | Async | Parallel | Tests Coverage |
|---|---|---|---|
| empty | emptyAsync | emptyParallel | Test |
| enumerateObject | enumerateObjectAsync | N/A | Test |
| flatten | flattenAsync | flattenParallel | Test |
| partition | partitionAsync | partitionParallel | Test |
| range | rangeAsync | rangeParallel | Test |
| repeat | repeatAsync | repeatParallel | Test |
Index Methods
| Method | Notes |
|---|---|
| bindArray | Binds IEnumerable methods to an ArrayLike Iterable type |
| bindLinq | Binds IEnumerable methods to an Interable type |
| bindLinqAsync | Binds IAsyncEnumerable methods to an AsyncIterable type |
| isEnumerable | Determines if source implements IEnumerable |
| isAsyncEnumerable | Determines if source implements IAsyncEnumerable |
| isParallelEnumerable | Determines if source implements IParallelEnumerable |
| initializeLinq | Binds to IEnumerable to Array Types, Map, Set, & String |
Exception Types
| Exception | Notes |
|---|---|
| ArgumentOutOfRangeException | Thrown when a passed in argument is invalid |
| InvalidOperationException | Thrown when no elements or no predicate match |
TypeDoc Documentation
Refer to https://arogozine.github.io/linqtotypescript/
Design
Binding new APIs to Array Types
JavaScript doesn't have extension methods like in C#, therefore we extend the class itself with new methods.
Call initializeLinq to bind library functions to default Array methods,
The following collections support IEnumerable,
ArrayMapSetStringInt8ArrayInt16ArrayInt32ArrayUint8ArrayUint8ClampedArrayUint16ArrayUint32ArrayFloat32ArrayFloat64Array
Using Wrappers
NOTE: Wrappers are safer as they won't interfere with other libraries.
// To Create an IEnumerable<T>
import { from } from "linq-to-typescript"
from(iterableIteratorOrArray)
// To Create an IAsyncEnumerable<T>
import { fromAsync } from "linq-to-typescript"
fromAsync(asyncIterableIteratorOrPromiseArray)
// To Create an IParallelEnumerable<T>
// You have to specify the parallel generator function type
import { fromParallel, ParallelGeneratorType } from "linq-to-typescript"
fromParallel(ParallelGeneratorType.PromiseToArray, asyncFuncThatReturnsAnArray)F.A.Q.
Q
I am getting a Error: Cannot find module 'tslib' error.
A
This library depends on tslib. Run npm i tslib to solve the error.
Q Why did you create this?
A For fun and to gain understanding of TypeScript and Node Package Manager.
Q What's needed to target ES2018?
A This library uses iteration and async iteration. You may need polyfills for Iterator and AsyncIterator. Libraries such as core js have this.
Q Can this run in an ES5 browser like Internet Explorer.
A With the right transpiler, polyfills, and bundler. Its not recommended due to the size and most likely major performance impact.
Q How does this compare to other LINQ libraries?
A Other libraries tend to use eager evaluation and work with arrays instead of iterables.
Q Why should I use this instead of lodash or something similar?
A
- TypeScript first. Libraries which target JavaScript first do additional type checking which can have a negative impact on performance.
- This library uses iterators and generators. Evaluation is lazy, not eager like JS array operations. These are new language features which have no support in legacy browsers like IE11.
Q Which browsers are supported?
A
- Firefox, Chrome, and Edge. IE is not supported.
- A good bundler targeting ES5 should allow IE support (with proper ES6/ES7 polyfils).
Q Can I contribute?
A Please do!