Nigel  Uys

Nigel Uys

1669121709

Check The Type Of Your JavaScript Object using The instanceof Operator

Check the type of your JavaScript object using the instanceof operator.

The JavaScript instanceof operator is used to find out the type of objects or values you have in your code.

The instanceof syntax is as follows:

object instanceof Object;

// returns a boolean: true or false

The instanceof will test if the Object constructor is present in the object’s prototype chain.

The example code below shows how you can use the instanceof method to test the Person object instance:

class Person {}

let person = new Person();

console.log(person instanceof Person); // true
console.log(person instanceof Object); // true
console.log(person instanceof Boolean); // false

Because the person variable’s value is an instance of both Person and Object classes, the instanceof operator returns true.

But the person object is not an instance of the Boolean class, so the operator returns false.

The instanceof operator also works when you create an object from a function as shown below:

function Dog() {}

let dog = new Dog();

console.log(dog instanceof Dog); // true

As you can see, the dog variable is an instance of Dog, so the instanceof operator returns true.

JavaScript instanceof vs typeof

JavaScript also has the typeof operator that can be used to check the type of values you define in your code.

The typeof operator returns a string representing the type of the value. It is commonly used for built-in JavaScript types as shown below:

console.log(typeof "Hello"); // "string"
console.log(typeof 123); // "number"

The instanceof and typeof operators work in different ways.

The instanceof returns either true or false while the typeof returns the actual type name of the value.

In general, the instanceof is used for testing advanced and custom types, while typeof is used for common JavaScript types.

The code below shows the difference between the two operators:

class Person {}

let person = new Person();

console.log(person instanceof Person); // true
console.log(typeof person); // "object"

console.log("Hello" instanceof String); // false
console.log(typeof "Hello"); // "string"
console.log(typeof "Hello" == "string"); // true

console.log(true instanceof Boolean); // false
console.log(typeof true); // "boolean"

console.log(true instanceof "boolean"); // ERROR

Now you’ve learned how the instanceof operator works in JavaScript, as well as the difference between the instanceof and typeof operators.

I hope this tutorial has been useful for you. 🙏

Original article source at: https://sebhastian.com/

#javascript #object #type 

Check The Type Of Your JavaScript Object using The instanceof Operator

Learning Kotlin Type Alias Feature

Learn how to define an alternative name for your types using Kotlin type alias feature.

The Kotlin type alias feature allows you to define an alternative name for your types, no matter if the type is built-in or custom.

To create a type alias in Kotlin, you need to use the typealias keyword followed by the alias name and the alias type.

typealias [alias name] = [alias type]

For example, you can alias the String type as Str as shown below:

typealias Str = String // Str type equals String

val myString: Str = "Nathan"

Kotlin’s type alias feature allows you to create alternative, shorter names for long type names.

The typealias keyword can be used for Kotlin classes, functions, and generic types.

Below is an example of a Kotlin class alias:

class UniqueIdentifier(var value: String)

typealias Uid = UniqueIdentifier

val userId = Uid("0001")

Next, you can also create an alias of function types:

typealias Length = (String) -> Int

val checkLength: Length = { it.length }

println(checkLength("Nathan")) // 6

The checkLength variable is essentially a function that accepts a String parameter and returns an Int value.

When developing Android applications, you can create an alias of Android R properties:

typealias Id = R.id
typealias Layout = R.layout
typealias Drawable = R.drawable

//...

setContentView(Layout.activity_main)
val button = findViewById<Button>(Id.button_id)

Type alias can also be used in place of import as follows:

typealias Text =  android.widget.TextView

// equals to..

import android.widget.TextView as Text

But it’s not recommended to use typealias in place of import unless you have a strong reason.

Kotlin type aliases don’t introduce new types because Kotlin replaces any alias with the real type during compile time.

This means the generated Java code executed during runtime uses the original type.

Error when using typealias

When running the examples below, you might see Kotlin throw an error saying:

Nested and local type aliases are not supported

This is an issue with Kotlin that has been resolved in the latest version. You need to make sure that the Kotlin library you use is >=1.6.10.

Also, the error will always appear when you run Kotlin code as a Scratch file in IntelliJ IDEA or Android Studio.

A typealias must be defined outside of a function as follows:

typealias Str = String

fun main() {
    val name: Str = "Nathan"
    println(name)
}

When the Nested and local type aliases are not supported error message is thrown, most likely there are aliases defined inside a function as shown below:

fun main() {
    typealias Str = String
    val name: Str = "Nathan"
    println(name)
}

This is why typealias always cause an error when run from Scratch files. All the code you write there is executed as if it would be in the body of the main function.

When aliasing a class, you can declare the typealias and the class as shown below:

class UniqueIdentifier(var value: String)
typealias uid = UniqueIdentifier

fun main() {
    val userId = uid("0001")
    println(userId.value)
}

The typealias must be positioned outside of the main function.

Great work on learning about Kotlin type alias. 👍

Original article source at: https://sebhastian.com/

#kotlin #type 

Learning Kotlin Type Alias Feature

How to PHP Illegal Offset Type Error Solved

PHP illegal offset type error solved

See how you can solve the illegal offset type error in PHP

PHP illegal offset type error occurs when you try to access an array using an object or an array as the key.

The PHP array keys are defined using string or int data type as shown below:

<?php
$user[0] = "Nathan";
$user[1] = "Jane";
$user["three"] = "John";

$obj = new stdClass();

print $user[0];
print $user[$obj]; // error

When you try to access an array using $obj as shown in the example above, PHP will throw the illegal offset type error:

Fatal error: Uncaught TypeError: Illegal offset type
  in /home/code.php:9

To resolve this error, you need to make sure that you are accessing the array correctly.

This error also frequently occurs when you are iterating over an array as follows:

<?php
$keys = [0, 1, new StdClass(), 2];

$array = ["Nathan", "John", "Jane", "Mary"];

foreach ($keys as $key) {
    print $array[$key] . PHP_EOL; // error
}

Because there is an object in the $keys array, PHP will throw the illegal offset type error when the iteration reaches that object.

You can use print_r() or var_dump() to check on the values of $keys in the example above:

print_r($keys);

You need to see the values of the $keys variable and make sure that you are not using an object or an array. The above code will show the following output:

Array
(
    [0] => 0
    [1] => 1
    [2] => stdClass Object
        (
        )
    [3] => 2
)

Once you see the value that causes the error, you need to remove it from your $keys array.

And that’s how you solve the PHP illegal offset type error.

Original article source at: https://sebhastian.com/php-illegal-offset-type/

#php #type #error

How to PHP Illegal Offset Type Error Solved
Sheldon  Grant

Sheldon Grant

1668496800

How to Python Type Checking

Python Type Checking

What is type checking? Why do we need it? What's the difference between static and runtime type checking?

Python is a strongly typed, dynamic programming language. With it being dynamically typed, types are dynamically inferred, so you can set variable values directly without defining the variable type like in statically typed programming languages such as Java.

Python is a strongly typed, dynamic programming language. With it being dynamically typed, types are dynamically inferred, so you can set variable values directly without defining the variable type like in statically typed programming languages such as Java.

name = "Michael"
String name = "Michael";

static vs dynamic programming languages

Strong and dynamic means that types are inferred at runtime but you can't mix types. For example, a = 1 + '0' will raise an error in Python. On the other hand, JavaScript is weak and dynamic, so types are inferred at runtime and you can mix types. For example, a = 1 + '0' will set a to 10.

While dynamic typing brings flexibility, it isn't always desirable so, there have been a number of efforts as of late to bring static type inference to dynamic languages.

In this article, we'll look at what type hints are and how they can benefit you. We'll also dive into how you can use Python's type system for static type checking with mypy and runtime type checking with pydantic, marshmallow, and typeguard.

The Complete Python Guide:

  1. Modern Python Environments - dependency and workspace management
  2. Testing in Python
  3. Modern Test-Driven Development in Python
  4. Python Code Quality
  5. Python Type Checking (this article!)
  6. Documenting Python Code and Projects
  7. Python Project Workflow

Tools

There are a number of tools out there that use type hints for static and runtime type checking.

Static typing

  1. mypy
  2. pyre
  3. Pyright
  4. pytype
  5. pyanalyze

Runtime type checking / data validation

  1. marshmallow
  2. pydantic
  3. typeguard
  4. typical
  5. pytypes

Project specific

  1. pydantic-django
  2. django-stubs
  3. typeddjango
  4. flask-pydantic
  5. flask-marshmallow
  6. fastapi (pydantic is built in -- yay!)

Check out Awesome Python Typing for a full list of tools.

Type Hints

Type hints were added to Python in version 3.5.

They allow developers to annotate expected types for variables, function parameters, and function returns inside Python code. While such types are not enforced by the Python interpreter -- again, Python is a dynamically typed language -- they do offer a number of benefits. First and foremost, with type hints, you can better express the intent of what it is that your code is doing and how to use it. Better understanding results in fewer bugs.

For example, say you have the following function to calculate the average daily temperature:

def daily_average(temperatures):
    return sum(temperatures) / len(temperatures)

As long as you provide a list of temperatures like so, the function works as intended and it will return the expected result:

average_temperature = daily_average([22.8, 19.6, 25.9])
print(average_temperature)  # => 22.76666666666667

What happens if you call the function with a dictionary where keys are timestamps of the measurements and values are temperatures?

average_temperature = daily_average({1599125906: 22.8, 1599125706: 19.6, 1599126006: 25.9})
print(average_temperature)  # => 1599125872.6666667

Essentially, this function now returns the sum of keys / number of keys, which is clearly wrong. Since the function call didn't raise an error, this can go undetected especially if the end user provides the temperatures.

To avoid such confusion, you can add type hints by annotating the argument and return value:

def daily_average(temperatures: list[float]) -> float:
    return sum(temperatures) / len(temperatures)

Now the function definition tells us:

  1. temperatures should be a list of floats: temperatures: list[float]
  2. the function should return a float: -> float
print(daily_average.__annotations__)
# {'temperatures': list[float], 'return': <class 'float'>}

Type hints enable static type checking tools. Code editors and IDEs use them as well, warning you when usage of a particular function or method is not as expected according to the type hints and providing powerful autocompletion.

So, type hints are really just "hints". They are not as strict as type definitions in statically typed languages, in other words. That said, even though they are quite flexible, they still help to improve code quality by expressing intentions more clearly. Besides that you can use a lot of tools to benefit from them even more.

Type Annotations vs Type Hints

Type annotations are just syntax to annotate function inputs, function outputs, and variables:

def sum_xy(x: 'an integer', y: 'another integer') -> int:
    return x + y


print(sum_xy.__annotations__)
# {'x': 'an integer', 'y': 'another integer', 'return': <class 'int'}

Type hints are built on top of annotations to make them more useful. Hints and annotations are often used interchangeably but they are different.

Python's typing Module

You may be wondering why sometimes you see code like this:

from typing import List


def daily_average(temperatures: List[float]) -> float:
    return sum(temperatures) / len(temperatures)

It's using the built-in float to define the function return type, but the List is imported from the typing module.

Before Python 3.9, the Python interpreter didn't support the use of built-ins with arguments for type hinting.

For example, it was possible to use list as a type hint like so:

def daily_average(temperatures: list) -> float:
    return sum(temperatures) / len(temperatures)

But it wasn't possible to define the expected type of list elements (list[float]) without the typing module. The same can be said for dictionaries and other sequences and complex types:

from typing import Tuple, Dict


def generate_map(points: Tuple[float, float]) -> Dict[str, int]:
    return map(points)

Besides that, the typing module allows you to define new types, type aliases, type Any and many other things.

For example, you may want to allow multiple types. For that you can use Union:

from typing import Union


def sum_ab(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
    return a + b

Since Python 3.9 you can use built-ins like so:

def sort_names(names: list[str]) -> list[str]:
    return sorted(names)

Static Type Checking with mypy

mypy is a tool for type checking at compile-time.

You can install it like any other Python package:

$ pip install mypy

To check your Python module you can run it like so:

$ python -m mypy my_module.py

So, let's look at the daily_average example again:

def daily_average(temperatures):
    return sum(temperatures) / len(temperatures)


average_temperature = daily_average(
    {1599125906: 22.8, 1599125706: 19.6, 1599126006: 25.9}
)

When type checking with mypy on such code, no errors will be reported since the function doesn't use type hints:

Success: no issues found in 1 source file

Add the type hints in:

def daily_average(temperatures: list[float]) -> float:
    return sum(temperatures) / len(temperatures)


average_temperature = daily_average(
    {1599125906: 22.8, 1599125706: 19.6, 1599126006: 25.9}
)

Run mypy again:

$ python -m mypy my_module.py

You should see:

my_module.py:6: error: Argument 1 to "daily_average" has incompatible
type "Dict[int, float]"; expected "List[float]"  [arg-type]

Found 1 error in 1 file (checked 1 source file)

mypy recognized that the function was being called incorrectly. It reported the file name, line number, and description of the error. Using type hints in conjunction with mypy can help reduce the number of errors resulting from the misuse of functions, methods, and classes. This results in quicker feedback loops. You don't need to run all of your tests or even deploy the whole application. You're notified about such errors immediately.

It's also a good idea to add mypy to your CI pipeline as well to check typing before your code is merged or deployed. For more on this, review the Python Code Quality article.

Although it's a big improvement in terms of code quality, static type checking doesn't enforce types at runtime, as your program is running. That's why we also have runtime type checkers, which we'll look at next.

mypy comes with typeshed which contains external type annotations for the Python standard library and Python built-ins as well as third-party packages.

mypy checks Python programs with basically no runtime overhead. Although it checks types, duck typing still happens. Therefore, it cannot be used to compile CPython extensions.

Runtime Type Checking

pydantic

Static type checkers don't help when dealing with data from external sources like the users of your application. That's where runtime type checkers come into play. One such tool is pydantic, which is used to validate data. It raises validation errors when the provided data does not match a type defined with a type hint.

pydantic uses type casting to convert input data to force it to conform to the expected type.

$ pip install pydantic

It's actually quite simple to use. For example, let's define a Song class with a few attributes:

from datetime import date

from pydantic import BaseModel


class Song(BaseModel):
    id: int
    name: str
    release: date
    genres: list[str]

Now, when we initialize a new Song with valid data, everything works as expected:

song = Song(
    id=101,
    name='Bohemian Rhapsody',
    release='1975-10-31',
    genres=[
        'Hard Rock',
        'Progressive Rock'
    ]
)
print(song)
# id=101 name='Bohemian Rhapsody' release=datetime.date(1975, 10, 31)
# genres=['Hard Rock', 'Progressive Rock']

However, when we try to initialize a new Song with invalid data ('1975-31-31'), a ValidationError is raised:

song = Song(
    id=101,
    name='Bohemian Rhapsody',
    release='1975-31-31',
    genres=[
        'Hard Rock',
        'Progressive Rock'
    ]
)
print(song)
# pydantic.error_wrappers.ValidationError: 1 validation error for Song
# release
#   invalid date format (type=value_error.date)

With pydantic, we can ensure that only data that matches the defined types are used in our application. This results not only in fewer bugs but you'll need to write fewer tests as well. By using tools such as pydantic we don't need to write tests for cases where the user sends completely wrong data. It's handled by pydantic -- a ValidationError is raised. For example, FastAPI validates HTTP request and response bodies with pydantic:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    price: float


@app.post("/items/", response_model=Item)
async def create_item(item: Item):
    return item

The create_item handler expects a payload with a name (string) and price (float). The response object should look the same. Now, if there's an issue with the provided payload, an error is raised right away. Raising it late makes it harder to debug and to determine where the data of the wrong type came from. Plus, since it's handled by pydantic, you can keep your route handlers clean.

Along with leveraging type hints for data validation, you can also add custom validators to ensure correctness of data beyond its type. Adding custom validation for an attribute is fairly easy. For example, to prevent genre duplications in the Song class, you can add validation like so:

from datetime import date

from pydantic import BaseModel, validator


class Song(BaseModel):
    id: int
    name: str
    release: date
    genres: list[str]

    @validator('genres')
    def no_duplicates_in_genre(cls, v):
        if len(set(v)) != len(v):
            raise ValueError(
                'No duplicates allowed in genre.'
            )
        return v


song = Song(
    id=101,
    name='Bohemian Rhapsody',
    release='1975-10-31',
    genres=[
        'Hard Rock',
        'Progressive Rock',
        'Progressive Rock',
    ]
)
print(song)
# pydantic.error_wrappers.ValidationError: 1 validation error for Song
# genre
#   No duplicates allowed in genre. (type=value_error)

So, the validation method, no_duplicates_in_genre, must be decorated with validator, which takes the attribute name as an argument. The validation method must be a class method since validation happens before the instance is created. For data that fails validation it should raise a standard Python ValueError.

You can also use validator methods to alter the value before validation occurs. To do so, add pre=True and always=True to the validator decorator:

@validator('genres', pre=True, always=True)

For example, you can convert genres to lower case like so:

from datetime import date

from pydantic import BaseModel, validator


class Song(BaseModel):
    id: int
    name: str
    release: date
    genres: list[str]

    @validator('genres', pre=True, always=True)
    def to_lower_case(cls, v):
        return [genre.lower() for genre in v]

    @validator('genres')
    def no_duplicates_in_genre(cls, v):
        if len(set(v)) != len(v):
            raise ValueError(
                'No duplicates allowed in genre.'
            )
        return v


song = Song(
    id=101,
    name='Bohemian Rhapsody',
    release='1975-10-31',
    genres=[
        'Hard Rock',
        'PrOgReSsIvE ROCK',
        'Progressive Rock',
    ]
)
print(song)
# pydantic.error_wrappers.ValidationError: 1 validation error for Song
# genre
#   No duplicates allowed in genre. (type=value_error)

to_lower_case converts every element in the genres list to lowercase. Because pre is set to True this method is called before pydantic validates the types. All generes are converted to lowercase and then validated with no_duplicates_in_genre.

pydantic also offers more strict types like PositiveInt and EmailStr to make your validations even better. Review Field Types from the docs for more on this.

Marshmallow

Another tool worth mentioning is marshmallow, which helps to validate complex data and load/dump data from/to native Python types. Installation is the same as for any other Python package:

$ pip install marshmallow

Like pydantic, you can add type validation to a class:

from marshmallow import Schema, fields, post_load


class Song:
    def __init__(
            self,
            id,
            name,
            release,
            genres
    ):
        self.id = id
        self.name = name
        self.release = release
        self.genres = genres

    def __repr__(self):
        return (
            f'<Song(id={self.id}, name={self.name}), '
            f'release={self.release.isoformat()}, genres={self.genres}>'
        )


class SongSchema(Schema):
    id = fields.Int()
    name = fields.Str()
    release = fields.Date()
    genres = fields.List(fields.String())

    @post_load
    def make_song(self, data, **kwargs):
        return Song(**data)


external_data = {
    'id': 101,
    'name': 'Bohemian Rhapsody',
    'release': '1975-10-31',
    'genres': ['Hard Rock', 'Progressive Rock']
}

song = SongSchema().load(external_data)
print(song)
# <Song(id=101, name=Bohemian Rhapsody), release=1975-10-31, genres=['Hard Rock', 'Progressive Rock']>

Unlike pydantic, marshmallow doesn't use type casting, so you need to define the schema and class separately. For example, release date in external_data must be an ISO string. It doesn't work with a datetime object.

To enable deserializing data into a Song object, you need to add a method decorated with @post_load decorator to the schema:

class SongSchema(Schema):
    id = fields.Int()
    name = fields.Str()
    release = fields.Date()
    genres = fields.List(fields.String(), validate=no_duplicates)

    @post_load
    def make_song(self, data, **kwargs):
        return Song(**data)

The schema validates the data and if all fields are valid, it creates an instance of the class by calling make_song with the validated data.

Like pydantic, you can add custom validations for each attribute from the schema. For example, you can prevent duplicates like so:

import datetime

from marshmallow import Schema, fields, post_load, ValidationError


class Song:
    def __init__(
            self,
            id,
            name,
            release,
            genres
    ):
        self.id = id
        self.name = name
        self.release = release
        self.genres = genres

    def __repr__(self):
        return (
            f'<Song(id={self.id}, name={self.name}), '
            f'release={self.release.isoformat()}, genres={self.genres}>'
        )


def no_duplicates(genres):
    if isinstance(genres, list):
        genres = [
            genre.lower()
            for genre in genres
            if isinstance(genre, str)
        ]

        if len(set(genres)) != len(genres):
            raise ValidationError(
                'No duplicates allowed in genres.'
            )


class SongSchema(Schema):
    id = fields.Int()
    name = fields.Str()
    release = fields.Date()
    genres = fields.List(fields.String(), validate=no_duplicates)

    @post_load
    def make_song(self, data, **kwargs):
        return Song(**data)


external_data = {
    'id': 101,
    'name': 'Bohemian Rhapsody',
    'release': '1975-10-31',
    'genres': ['Hard Rock', 'Progressive Rock', 'ProgressivE Rock']
}

song = SongSchema().load(external_data)
print(song)
# marshmallow.exceptions.ValidationError:
# {'genres': ['No duplicates allowed in genres.']}

As you can see, you can use either pydantic or marshmallow to ensure data has the correct type as your application runs. Pick the one that fits your style better.

Typeguard

While pydantic and marshmallow focus on data validation and serialization, typeguard focuses on checking types as functions are called. While mypy just does static type checking, typeguard enforces types while your program is running.

$ pip install typeguard

Let's take a look at the same example as before -- a Song class. This time we define it's __init__ method with type hinted arguments:

from datetime import date

from typeguard import typechecked


@typechecked
class Song:

    def __init__(
            self,
            id: int,
            name: str,
            release: date,
            genres: list[str]

    ) -> None:
        self.id = id
        self.name = name
        self.release = release
        self.genres = genres


song = Song(
    id=101,
    name='Bohemian Rhapsody',
    release=date(1975, 10, 31),
    genres={
        'Hard Rock',
        'Progressive Rock',
    }
)
print(song)
# TypeError: type of argument "genres" must be a list; got set instead

The typechecked decorator can be used for both classes and functions when you want to enforce type checking during runtime. Running this code will raise a TypeError since genres are a set instead of a list. You can similarly use a decorator for functions like so:

from typeguard import typechecked

@typechecked
def sum_ab(a: int, b: int) -> int:
    return a + b

It also comes with a pytest plugin. To check types for package my_package while running tests you can run this command:

$ python -m pytest --typeguard-packages=my_package

When running with pytest you don't need to use the @typechecked decorator. So, you can either decorate your functions and classes to enforce types during runtime or just during test runs. Either way, typeguard can be a powerful safety net for your application to ensure it runs as expected.

Flask with pydantic

So let's put it all together into a web application. As mentioned above, FastAPI uses pydantic by default. Although Flask doesn't have built-in support for pydantic we can use bindings to also add it to our APIs. So let's create a new Flask project to see it in action.

First, create a new folder:

$ mkdir flask_example
$ cd flask_example

Next, initialize your project with Poetry:

$ poetry init
Package name [flask_example]:
Version [0.1.0]:
Description []:
Author [Your name <your@email.com>, n to skip]:
License []:
Compatible Python versions [^3.7]:  >3.7

Would you like to define your main dependencies interactively? (yes/no) [yes] no
Would you like to define your development dependencies interactively? (yes/no) [yes] no
Do you confirm generation? (yes/no) [yes]

After that, add Flask, Flask-Pydantic, and pytest:

$ poetry add flask Flask-Pydantic
$ poetry add --dev pytest

Create a file to hold our tests called test_app.py:

import json

import pytest

from app import app


@pytest.fixture
def client():
    app.config["TESTING"] = True

    with app.test_client() as client:
        yield client


def test_create_todo(client):
    response = client.post(
        "/todos/",
        data=json.dumps(
            {
                'title': 'Wash the dishes',
                'done': False,
                'deadline': '2020-12-12'
            }
        ),
        content_type='application/json'
    )

    assert response.status_code == 201


def test_create_todo_bad_request(client):
    response = client.post(
        "/todos/",
        data=json.dumps(
            {
                'title': 'Wash the dishes',
                'done': False,
                'deadline': 'WHENEVER'
            }
        ),
        content_type='application/json'
    )

    assert response.status_code == 400

Here, we have two tests for creating new todos. One checks that a status of 201 is returned when everything is fine. Another checks that a status of 400 is returned when the provided data is not as expected.

Next, add a file for the Flask app called app.py:

import datetime

from flask import Flask, request
from flask_pydantic import validate
from pydantic import BaseModel

app = Flask(__name__)


class CreateTodo(BaseModel):
    title: str
    done: bool
    deadline: datetime.date


class Todo(BaseModel):
    title: str
    done: bool
    deadline: datetime.date
    created_at: datetime.datetime


@app.route("/todos/", methods=['POST'])
@validate(body=CreateTodo)
def todos():
    todo = Todo(
        title=request.body_params.title,
        done=request.body_params.done,
        deadline=request.body_params.deadline,
        created_at=datetime.datetime.now()
    )

    return todo, 201


if __name__ == "__main__":
    app.run()

We've defined an endpoint for creating todos along with a request schema called CreateTodo and a response schema called Todo. Now when data is sent to the API that does not match the request schema a status of 400 with validation errors in the body is returned. You can run tests now to check that your API is actually behaving as described:

$ poetry run pytest

Running Type Checkers

Now that you know the tools, the next question is: When should they be used?

Much like code quality tools, you typically run type checkers:

  1. While coding (inside your IDE or code editor)
  2. At commit time (with pre-commit hooks)
  3. When code is checked in to source control (via a CI pipeline)
  4. During program run (runtime checkers)

Inside Your IDE or Code Editor

It's best to check for issues that could have a negative impact on quality early and often. Therefore, it's recommended to statically check your code during development. Many of the popular IDEs have mypy or mypy-like static type checkers built in. For those that don't, there's likely a plugin available. Such plugins warn you in real-time about type violations and potential programming errors.

Resources:

  1. Adding type hints in PyCharm
  2. Type hints in Visual Studio Code
  3. Sublime Text Package Finder
  4. Atom Packages

Pre-commit Hooks

Since you'll inevitably miss a warning here and there as you're coding, it's a good practice to check for static type issues at commit time with pre-commit git hooks. This way you can avoid committing code that won't pass type checks inside your CI pipeline.

The pre-commit framework is recommended for managing git hooks.

$ pip install pre-commit

Once installed, add a pre-commit config file called .pre-commit-config.yaml to your project. To run mypy, add the following config:

repos:
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: 'v0.790'
    hooks:
      - id: mypy

Finally, to set up the git hook scripts:

(venv)$ pre-commit install

Now, every time you run git commit mypy will run before the actual commit is made. And if there are any issues, the commit will be aborted.

CI Pipeline

It makes sense to run static type checks inside your CI pipeline to prevent type issues to be merged into the code base. This is probably the most important time to run mypy or some other static type checker.

You may experience issues when running static type checks with mypy, especially when using third-party libraries without type hints. That's probably the major reason why many people avoid running mypy checks inside the CI pipeline.

During Program Run

All previous times to run are before your program is actually running. That's the job for static type checkers. For dynamic type checkers you need a running program. As mentioned before, using them will require less tests, produce less bugs, and help you detect bugs early. You can use them for data validations (with pydantic and marshmallow) and to enforce types during program run (with typeguard).

Conclusion

Type checking may seem unnecessary when a code base is small, but the larger it gets, the more important it is. It's one more layer that protects us against easily preventable bugs. Type hints, although they're not enforced by the interpreter, help to better express the intent of a variable, function, or class. Most modern IDEs and code editors provide plugins to notify developers about type mismatches based on type hints. To enforce them, we can include mypy into our workflow to statically check whether usage of methods match their type hints. Although static analysis can improve your code, you must take into account that our software is communicating with the external world. Because of that, it's encouraged to add runtime type checkers like pydantic or marshmallow. They help with validating user input and raise errors at the earliest possible stage. The faster you find an error, the easier it is to correct it and move on.

The Complete Python Guide:

  1. Modern Python Environments - dependency and workspace management
  2. Testing in Python
  3. Modern Test-Driven Development in Python
  4. Python Code Quality
  5. Python Type Checking (this article!)
  6. Documenting Python Code and Projects
  7. Python Project Workflow

Original article source at: https://testdriven.io/

#python #type 

How to Python Type Checking

How to Get The Variable Type in PHP

How you can find the type of variables you have in your PHP codebase.

To get the type of variables you have in your code, you can use the PHP gettype() or var_dump() function.

The PHP gettype() function returns a string that shows the type of the variable you passed as its argument:

$myVar = "Hello";

print gettype($myVar); // string

print gettype(999); // integer

$arr = [1, 2, "A"];
print gettype($arr); // array

The var_dump() function returns a structured information from an expression.

This var_dump() can be used to get the type and value that your variable holds.

Unlike gettype() which returns a string value, var_dump() directly produces an output to the browser. You don’t need to add print or echo before calling the function:

$myVar = "Hello";

var_dump($myVar);

var_dump(999);

$arr = [1, 2, "A"];
var_dump($arr);

The code above will produce the following output:

string(5) "Hello"
int(999)
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  string(1) "A"
}

When you pass a string value, the var_dump() function also returns the length of the string as you see in the example above.

When you need the variable type returned as a string, you should use the gettype() function.

If you are debugging an issue during development, you may want to use the var_dump() function as it gives you more information about a specific variable.

Now you’ve learned how to get the variable type in PHP. Nice work!

Original article source at: https://sebhastian.com/ 

#php #type #variables 

How to Get The Variable Type in PHP
Lawrence  Lesch

Lawrence Lesch

1668077768

Utility-types: Collection Of Utility Types

utility-types

Collection of utility types, complementing TypeScript built-in mapped types and aliases (think "lodash" for static types).

Found it useful? Want more updates? 


What's new?

🎉 Now updated to support TypeScript v3.7 🎉


Features

Goals

  • Quality - thoroughly tested for type correctness with type-testing library dts-jest
  • Secure and minimal - no third-party dependencies
  • No runtime cost - it's type-level only

Installation

# NPM
npm install utility-types

# YARN
yarn add utility-types

Compatibility Notes

TypeScript support

  • v3.x.x - TypeScript v3.1+
  • v2.x.x - TypeScript v2.8.1+
  • v1.x.x - TypeScript v2.7.2+

Funding Issues

Utility-Types is an open-source project created by people investing their time for the benefit of our community.

Issues like bug fixes or feature requests can be very quickly resolved when funded through the IssueHunt platform.

I highly recommend adding a bounty to the issue that you're waiting for to attract some contributors willing to work on it.

Let's fund issues in this repository

Contributing

We are open for contributions. If you're planning to contribute please make sure to read the contributing guide as it can save you from wasting your time: CONTRIBUTING.md


  • (built-in) - types built-in TypeScript, no need to import

Table of Contents

Aliases & Type Guards

Union operators

Object operators

Special operators

Flow's Utility Types

Deprecated API (use at own risk)

  • getReturnOfExpression() - from TS v2.0 it's better to use type-level ReturnType instead

Primitive

Type representing primitive types in JavaScript, and thus TypeScript: string | number | bigint | boolean | symbol | null | undefined

You can test for singular of these types with typeof

isPrimitive

This is a TypeScript Typeguard for the Primitive type.

This can be useful to control the type of a parameter as the program flows. Example:

const consumer = (param: Primitive[] | Primitive): string => {
    if (isPrimitive(param)) {
        // typeof param === Primitive
        return String(param) + ' was Primitive';
    }
    // typeof param === Primitive[]
    const resultArray = param
        .map(consumer)
        .map(rootString => '\n\t' + rootString);
    return resultArray.reduce((comm, newV) => comm + newV, 'this was nested:');
};

Falsy

Type representing falsy values in TypeScript: false | "" | 0 | null | undefined

Except NaN which cannot be represented as a type literal

isFalsy

const consumer = (param: Falsy | string): string => {
    if (isFalsy(param)) {
        // typeof param === Falsy
        return String(param) + ' was Falsy';
    }
    // typeof param === string
    return param.toString();
};

Nullish

Type representing nullish values in TypeScript: null | undefined

isNullish

const consumer = (param: Nullish | string): string => {
    if (isNullish(param)) {
        // typeof param === Nullish
        return String(param) + ' was Nullish';
    }
    // typeof param === string
    return param.toString();
};

SetIntersection<A, B> (same as Extract)

Set intersection of given union types A and B

Usage:

import { SetIntersection } from 'utility-types';

// Expect: "2" | "3"
type ResultSet = SetIntersection<'1' | '2' | '3', '2' | '3' | '4'>;
// Expect: () => void
type ResultSetMixed = SetIntersection<string | number | (() => void), Function>;

SetDifference<A, B> (same as Exclude)

Set difference of given union types A and B

Usage:

import { SetDifference } from 'utility-types';

// Expect: "1"
type ResultSet = SetDifference<'1' | '2' | '3', '2' | '3' | '4'>;
// Expect: string | number
type ResultSetMixed = SetDifference<string | number | (() => void), Function>;

SetComplement<A, A1>

Set complement of given union types A and (it's subset) A1

Usage:

import { SetComplement } from 'utility-types';

// Expect: "1"
type ResultSet = SetComplement<'1' | '2' | '3', '2' | '3'>;

SymmetricDifference<A, B>

Set difference of union and intersection of given union types A and B

Usage:

import { SymmetricDifference } from 'utility-types';

// Expect: "1" | "4"
type ResultSet = SymmetricDifference<'1' | '2' | '3', '2' | '3' | '4'>;

NonNullable<A>

Exclude null and undefined from set A

NonUndefined<A>

Exclude undefined from set A

Exclude<A, B>

Exclude subset B from set A

Extract<A, B>

Extract subset B from set A

Operations on objects

FunctionKeys<T>

Get union type of keys that are functions in object type T

Usage:

import { FunctionKeys } from 'utility-types';

type MixedProps = { name: string; setName: (name: string) => void };

// Expect: "setName"
type Keys = FunctionKeys<MixedProps>;

NonFunctionKeys<T>

Get union type of keys that are non-functions in object type T

Usage:

import { NonFunctionKeys } from 'utility-types';

type MixedProps = { name: string; setName: (name: string) => void };

// Expect: "name"
type Keys = NonFunctionKeys<MixedProps>;

MutableKeys<T>

Get union type of keys that are mutable (not readonly) in object type T

Alias: WritableKeys<T>

Usage:

import { MutableKeys } from 'utility-types';

type Props = { readonly foo: string; bar: number };

// Expect: "bar"
type Keys = MutableKeys<Props>;

ReadonlyKeys<T>

Get union type of keys that are readonly in object type T

Usage:

import { ReadonlyKeys } from 'utility-types';

type Props = { readonly foo: string; bar: number };

// Expect: "foo"
type Keys = ReadonlyKeys<Props>;

RequiredKeys<T>

Get union type of keys that are required in object type T

Usage:

import { RequiredKeys } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; optUndef?: number | undefined; };

// Expect: "req" | "reqUndef"
type Keys = RequiredKeys<Props>;

OptionalKeys<T>

Get union type of keys that are optional in object type T

Usage:

import { OptionalKeys } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; optUndef?: number | undefined; };

// Expect: "opt" | "optUndef"
type Keys = OptionalKeys<Props>;

Optional<T, K>

From T make a set of properties by key K become optional

Usage:

import { Optional } from 'utility-types';

type Props = { name: string; age: number; visible: boolean; };

// Expect: { name?: string; age?: number; visible?: boolean; }
type Props = Optional<Props>
// Expect: { name: string; age?: number; visible?: boolean; }
type Props = Optional<Props, 'age' | 'visible'>;

Pick<T, K> (built-in)

From T pick a set of properties by key K

Usage:

type Props = { name: string; age: number; visible: boolean };

// Expect: { age: number; }
type Props = Pick<Props, 'age'>;

PickByValue<T, ValueType>

From T pick a set of properties by value matching ValueType. (Credit: Piotr Lewandowski)

Usage:

import { PickByValue } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; };

// Expect: { req: number }
type Props = PickByValue<Props, number>;
// Expect: { req: number; reqUndef: number | undefined; }
type Props = PickByValue<Props, number | undefined>;

PickByValueExact<T, ValueType>

From T pick a set of properties by value matching exact ValueType.

Usage:

import { PickByValueExact } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; };

// Expect: { req: number }
type Props = PickByValueExact<Props, number>;
// Expect: { reqUndef: number | undefined; }
type Props = PickByValueExact<Props, number | undefined>;

Omit<T, K>

From T remove a set of properties by key K

Usage:

import { Omit } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: { name: string; visible: boolean; }
type Props = Omit<Props, 'age'>;

OmitByValue<T, ValueType>

From T remove a set of properties by value matching ValueType. (Credit: Piotr Lewandowski)

Usage:

import { OmitByValue } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; };

// Expect: { reqUndef: number | undefined; opt?: string; }
type Props = OmitByValue<Props, number>;
// Expect: { opt?: string; }
type Props = OmitByValue<Props, number | undefined>;

OmitByValueExact<T, ValueType>

From T remove a set of properties by value matching exact ValueType.

Usage:

import { OmitByValueExact } from 'utility-types';

type Props = { req: number; reqUndef: number | undefined; opt?: string; };

// Expect: { reqUndef: number | undefined; opt?: string; }
type Props = OmitByValueExact<Props, number>;
// Expect: { req: number; opt?: string }
type Props = OmitByValueExact<Props, number | undefined>;

Intersection<T, U>

From T pick properties that exist in U

Usage:

import { Intersection } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };

// Expect: { age: number; }
type DuplicatedProps = Intersection<Props, DefaultProps>;

Diff<T, U>

From T remove properties that exist in U

Usage:

import { Diff } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };

// Expect: { name: string; visible: boolean; }
type RequiredProps = Diff<Props, DefaultProps>;

Subtract<T, T1>

From T remove properties that exist in T1 (T1 has a subset of the properties of T)

Usage:

import { Subtract } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };

// Expect: { name: string; visible: boolean; }
type RequiredProps = Subtract<Props, DefaultProps>;

Overwrite<T, U>

From U overwrite properties to T

Usage:

import { Overwrite } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type NewProps = { age: string; other: string };

// Expect: { name: string; age: string; visible: boolean; }
type ReplacedProps = Overwrite<Props, NewProps>;

Assign<T, U>

From U assign properties to T (just like object assign)

Usage:

import { Assign } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type NewProps = { age: string; other: string };

// Expect: { name: string; age: string; visible: boolean; other: string; }
type ExtendedProps = Assign<Props, NewProps>;

ValuesType<T>

Get the union type of all the values in an object, tuple, array or array-like type T.

Usage:

import { ValuesType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string | number | boolean
type PropsValues = ValuesType<Props>;

type NumberArray = number[];
// Expect: number
type NumberItems = ValuesType<NumberArray>;

type ReadonlyNumberTuple = readonly [1, 2];
// Expect: 1 | 2
type AnotherNumberUnion = ValuesType<NumberTuple>;

type BinaryArray = Uint8Array;
// Expect: number
type BinaryItems = ValuesType<BinaryArray>;

Partial<T>

Make all properties of object type optional

Required<T, K>

From T make a set of properties by key K become required

Usage:

import { Required } from 'utility-types';

type Props = { name?: string; age?: number; visible?: boolean; };

// Expect: { name: string; age: number; visible: boolean; }
type Props = Required<Props>
// Expect: { name?: string; age: number; visible: boolean; }
type Props = Required<Props, 'age' | 'visible'>;

Readonly<T>

Make all properties of object type readonly

Mutable<T>

From T make all properties become mutable

Alias: Writable<T>

import { Mutable } from 'utility-types';

type Props = {
  readonly name: string;
  readonly age: number;
  readonly visible: boolean;
};

// Expect: { name: string; age: number; visible: boolean; }
Mutable<Props>;

ReturnType<T>

Obtain the return type of a function

InstanceType<T>

Obtain the instance type of a class

Unionize<T>

Disjoin object to form union of objects, each with single property

Usage:

import { Unionize } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: { name: string; } | { age: number; } | { visible: boolean; }
type UnionizedType = Unionize<Props>;

PromiseType<T>

Obtain Promise resolve type

Usage:

import { PromiseType } from 'utility-types';

// Expect: string
type Response = PromiseType<Promise<string>>;

DeepReadonly<T>

Readonly that works for deeply nested structures

Usage:

import { DeepReadonly } from 'utility-types';

type NestedProps = {
  first: {
    second: {
      name: string;
    };
  };
};

// Expect: {
//   readonly first: {
//     readonly second: {
//       readonly name: string;
//     };
//   };
// }
type ReadonlyNestedProps = DeepReadonly<NestedProps>;

DeepRequired<T>

Required that works for deeply nested structures

Usage:

import { DeepRequired } from 'utility-types';

type NestedProps = {
  first?: {
    second?: {
      name?: string;
    };
  };
};

// Expect: {
//   first: {
//     second: {
//       name: string;
//     };
//   };
// }
type RequiredNestedProps = DeepRequired<NestedProps>;

DeepNonNullable<T>

NonNullable that works for deeply nested structure

Usage:

import { DeepNonNullable } from 'utility-types';

type NestedProps = {
  first?: null | {
    second?: null | {
      name?: string | null | undefined;
    };
  };
};

// Expect: {
//   first: {
//     second: {
//       name: string;
//     };
//   };
// }
type RequiredNestedProps = DeepNonNullable<NestedProps>;

DeepPartial<T>

Partial that works for deeply nested structures

Usage:

import { DeepPartial } from 'utility-types';

type NestedProps = {
  first: {
    second: {
      name: string;
    };
  };
};

// Expect: {
//   first?: {
//     second?: {
//       name?: string;
//     };
//   };
// }
type PartialNestedProps = DeepPartial<NestedProps>;

Brand<T, U>

Define nominal type of U based on type of T. Similar to Opaque types in Flow.

Usage:

import { Brand } from 'utility-types';

type USD = Brand<number, "USD">
type EUR = Brand<number, "EUR">

const tax = 5 as USD;
const usd = 10 as USD;
const eur = 10 as EUR;

function gross(net: USD): USD {
  return (net + tax) as USD;
}

gross(usd); // ok
gross(eur); // Type '"EUR"' is not assignable to type '"USD"'.

UnionToIntersection<U>

Get intersection type given union type U

Usage:

import { UnionToIntersection } from 'utility-types';

// Expect: { name: string } & { age: number } & { visible: boolean }
UnionToIntersection<{ name: string } | { age: number } | { visible: boolean }>

Flow's Utility Types

$Keys<T>

get the union type of all the keys in an object type T
https://flow.org/en/docs/types/utilities/#toc-keys

Usage:

import { $Keys } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: "name" | "age" | "visible"
type PropsKeys = $Keys<Props>;

$Values<T>

get the union type of all the values in an object type T
https://flow.org/en/docs/types/utilities/#toc-values

Usage:

import { $Values } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: string | number | boolean
type PropsValues = $Values<Props>;

$ReadOnly<T>

get the read-only version of a given object type T
https://flow.org/en/docs/types/utilities/#toc-readonly

Usage:

import { $ReadOnly } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: Readonly<{ name: string; age: number; visible: boolean; }>
type ReadOnlyProps = $ReadOnly<Props>;

$Diff<T, U>

get the set difference of a given object types T and U (T \ U)
https://flow.org/en/docs/types/utilities/#toc-diff

Usage:

import { $Diff } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };

// Expect: { name: string; visible: boolean; }
type RequiredProps = $Diff<Props, DefaultProps>;

$PropertyType<T, K>

get the type of property of an object at a given key K
https://flow.org/en/docs/types/utilities/#toc-propertytype

Usage:

import { $PropertyType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string
type NameType = $PropertyType<Props, 'name'>;

type Tuple = [boolean, number];
// Expect: boolean
type A = $PropertyType<Tuple, '0'>;
// Expect: number
type B = $PropertyType<Tuple, '1'>;

$ElementType<T, K>

get the type of elements inside of array, tuple or object of type T, that matches the given index type K
https://flow.org/en/docs/types/utilities/#toc-elementtype

Usage:

import { $ElementType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string
type NameType = $ElementType<Props, 'name'>;

type Tuple = [boolean, number];
// Expect: boolean
type A = $ElementType<Tuple, 0>;
// Expect: number
type B = $ElementType<Tuple, 1>;

type Arr = boolean[];
// Expect: boolean
type ItemsType = $ElementType<Arr, number>;

type Obj = { [key: string]: number };
// Expect: number
type ValuesType = $ElementType<Obj, string>;

$Call<T>

get the return type of a given expression type
https://flow.org/en/docs/types/utilities/#toc-call

The built-in ReturnType can be used to accomplish the same goal, although it may have some subtle differences.

Usage:

import { $Call } from 'utility-types';

// Common use-case
const add = (amount: number) => ({ type: 'ADD' as 'ADD', payload: amount });
type AddAction = $Call<typeof add>; // { type: 'ADD'; payload: number }

// Examples migrated from Flow docs
type ExtractPropType<T extends { prop: any }> = (arg: T) => T['prop'];
type Obj = { prop: number };
type PropType = $Call<ExtractPropType<Obj>>; // number
// type Nope = $Call<ExtractPropType<{ nope: number }>>; // Error: argument doesn't match `Obj`.

type ExtractReturnType<T extends () => any> = (arg: T) => ReturnType<T>;
type Fn = () => number;
type FnReturnType = $Call<ExtractReturnType<Fn>>; // number

$Shape<T>

Copies the shape of the type supplied, but marks every field optional.
https://flow.org/en/docs/types/utilities/#toc-shape

Usage:

import { $Shape } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };

// Expect: Partial<Props>
type PartialProps = $Shape<Props>;

$NonMaybeType<T>

Converts a type T to a non-maybe type. In other words, the values of $NonMaybeType<T> are the values of T except for null and undefined.
https://flow.org/en/docs/types/utilities/#toc-nonmaybe

Usage:

import { $NonMaybeType } from 'utility-types';

type MaybeName = string | null;

// Expect: string
type Name = $NonMaybeType<MaybeName>;

Class<T>

Given a type T representing instances of a class C, the type Class is the type of the class C
https://flow.org/en/docs/types/utilities/#toc-class * Differs from original Flow's util - implements only constructor part and won't include any static members. Additionally classes in Typescript are not treated as nominal

Usage:

import { Class } from 'utility-types';


function makeStore(storeClass: Class<Store>): Store {
  return new storeClass();
}

mixed

An arbitrary type that could be anything (same as unknown)
https://flow.org/en/docs/types/mixed


Related Projects

  • ts-toolbelt - Higher type safety for TypeScript
  • $mol_type - Collection of TypeScript meta types for complex logic

Download Details:

Author: piotrwitek
Source Code: https://github.com/piotrwitek/utility-types 
License: MIT license

#typescript #utilities #static #type 

Utility-types: Collection Of Utility Types

Eyeball.jl: Object and Type Viewer for Julia

Eyeball.jl

Object and type viewer for Julia

Eyeball exports one main tool to browse Julia objects and types.

eye(object)
eye(object, depth)
eye(object = Main, depth = 10; interactive = true, all = false)

depth controls the depth of folding. all expands options.

The user can interactively browse the object tree using the following keys:

  • -- Up and down moves through the tree. Left collapses a tree. Right expands a folded tree. Vim movement keys (h j k l) are also supported.
  • d -- Docs. Show documentation on the object.
  • e -- Expand. Show more subobjects. The number of objects is doubled each time.
  • f -- Toggle fields. By default, parameters are shown for most objects. f toggles between the normal view and a view showing the fields of an object.
  • m -- Methodswith. Show methods available for objects of this type. M specifies supertypes = true.
  • o -- Open. Open the object in a new tree view. O opens all (mainly useful for modules).
  • r -- Return tree (a FoldingTrees.Node).
  • s -- Show object.
  • S -- Sort. Open the sorted object in a new view.
  • t -- Typeof. Show the type of the object in a new tree view.
  • z -- Summarize. Toggle a summary of the object and child objects. For arrays, this shows the mean and 0, 25, 50, 75, and 100% quantiles (skipping missings).
  • 0-9 -- Fold to depth. Also toggles expansion of items normally left folded.
  • enter -- Return the selected object.
  • q -- Quit.

Notes:

  • Longer objects only have the first few elements shown when unfolded. Use e to expand.
  • Some types are left folded by default (numbers, typed arrays, ...). The number keys for folding cycle between keeping these folded and unfolding these.
  • Some types are not recursed into. This includes modules. You can use o to open these in a new tree view.
  • O and all = true adds a wrapper Eyeball.All around the object. This is mainly for use with modules where options are taken with name(module, all = true).
  • Summarize z shows a summary of child objects. That's useful for DataFrames, nested arrays, and similar types.
  • For dictionaries with simple keys (symbols, strings, or numbers), the key is shown directly. For others, a list of key-value pairs is shown.

Examples

Explore an object:

a = (h=rand(5), e=:(5sin(pi*t)), f=sin, c=33im, set=Set((:a, 9, rand(1:5, 8))), b=(c=1,d=9,e=(i=9,f=0)), x=9 => 99:109, d=Dict(1=>2, 3=>4), ds=Dict(:s=>4,:t=>7), dm=Dict(1=>9, "x"=>8))
eye(a)
julia> eye(a)
[f] fields [d] docs [e] expand [m/M] methodswith [o] open [r] tree [s] show [t] typeof [z] summarize [q] quit
 >   : NamedTuple{(:h, :e, :f, :c, :set, :b, :x, :d, :ds, :dm), Tuple{Vector{Float64}, Expr, typeof(sin), Complex{Int64}   +  h: Vector{Float64} (5,) 40 [0.589398, 0.761107, 0.963494, 0.835393, 0.488657]
      e: Expr  :(5 * sin(pi * t))
       head: Symbol  :call
       args: Vector{Any} (3,) 24 Any[:*, 5, :(sin(pi * t))]
        1: Symbol  :*
        2: Int64  5
        3: Expr  :(sin(pi * t))
         head: Symbol  :call
         args: Vector{Any} (2,) 16 Any[:sin, :(pi * t)]
          1: Symbol  :sin
          2: Expr  :(pi * t)
           head: Symbol  :call
           args: Vector{Any} (3,) 24 Any[:*, :pi, :t]
            1: Symbol  :*
            2: Symbol  :pi
            3: Symbol  :t
      f: typeof(sin)  sin
   +  c: Complex{Int64}  0+33im
      set: Set{Any}  Set(Any[:a, 9, [2, 3, 2, 5, 5, 1, 4, 5]])
       : Symbol  :a
       : Int64  9
   +   : Vector{Int64} (8,) 64 [2, 3, 2, 5, 5, 1, 4, 5]
      b: NamedTuple{(:c, :d, :e), Tuple{Int64, Int64, NamedTuple{(:i, :f), Tuple{Int64, Int64}}}}  (c = 1, d = 9, e = (i       c: Int64  1
       d: Int64  9
       e: NamedTuple{(:i, :f), Tuple{Int64, Int64}}  (i = 9, f = 0)
        i: Int64  9
        f: Int64  0
   +  x: Pair{Int64, UnitRange{Int64}}  9=>99:109
      d: Dict{Int64, Int64}  Dict(3=>4, 1=>2)
       3: Int64  4
       1: Int64  2
      ds: Dict{Symbol, Int64}  Dict(:s=>4, :t=>7)
       s: Int64  4
v      t: Int64  7

Explore a Module:

eye()      # equivalent to `eye(Main)`

Expand results

julia> eye()
[f] fields [d] docs [e] expand [m/M] methodswith [o] open [r] tree [s] show [t] typeof [z] summarize [q] quit
 >   : Module  Main
      Base: Module  Base
      Core: Module  Core
      InteractiveUtils: Module  InteractiveUtils
      Main: Module  Main
      a: NamedTuple{(:h, :e, :f, :c, :set, :b, :x, :d, :ds, :dm), Tuple{Vector{Float64}, Expr, typeof(sin), Complex{Int6   +   h: Vector{Float64} (5,) 40 [0.589398, 0.761107, 0.963494, 0.835393, 0.488657]
       e: Expr  :(5 * sin(pi * t))
        head: Symbol  :call
        args: Vector{Any} (3,) 24 Any[:*, 5, :(sin(pi * t))]
         1: Symbol  :*
         2: Int64  5
         3: Expr  :(sin(pi * t))
          head: Symbol  :call
          args: Vector{Any} (2,) 16 Any[:sin, :(pi * t)]
           1: Symbol  :sin
           2: Expr  :(pi * t)
            head: Symbol  :call
            args: Vector{Any} (3,) 24 Any[:*, :pi, :t]
             1: Symbol  :*
             2: Symbol  :pi
             3: Symbol  :t
       f: typeof(sin)  sin
   +   c: Complex{Int64}  0+33im
       set: Set{Any}  Set(Any[:a, 9, [2, 3, 2, 5, 5, 1, 4, 5]])
        : Symbol  :a
        : Int64  9
   +    : Vector{Int64} (8,) 64 [2, 3, 2, 5, 5, 1, 4, 5]
       b: NamedTuple{(:c, :d, :e), Tuple{Int64, Int64, NamedTuple{(:i, :f), Tuple{Int64, Int64}}}}  (c = 1, d = 9, e = (        c: Int64  1
        d: Int64  9
        e: NamedTuple{(:i, :f), Tuple{Int64, Int64}}  (i = 9, f = 0)
         i: Int64  9
         f: Int64  0
   +   x: Pair{Int64, UnitRange{Int64}}  9=>99:109
v      d: Dict{Int64, Int64}  Dict(3=>4, 1=>2)

Explore a type tree:

eye(Number)

Expand results

julia> eye(Number)
[f] fields [d] docs [e] expand [m/M] methodswith [o] open [r] tree [s] show [t] typeof [z] summarize [q] quit
>   : DataType  Number
   +  : UnionAll  Complex
      : DataType  Real
       : DataType  AbstractFloat
   +    : DataType  BigFloat
        : DataType  Float16
        : DataType  Float32
        : DataType  Float64
       : DataType  AbstractIrrational
   +    : UnionAll  Irrational
       : DataType  Integer
        : DataType  Bool
        : DataType  Signed
   +     : DataType  BigInt
         : DataType  Int128
         : DataType  Int16
         : DataType  Int32
         : DataType  Int64
         : DataType  Int8
        : DataType  Unsigned
         : DataType  UInt128
         : DataType  UInt16
         : DataType  UInt32
         : DataType  UInt64
         : DataType  UInt8
   +   : UnionAll  Rational

Use noninteractively

With the keyword argument interactive set to false, eye returns the tree as a FoldingTrees.Node. That is automatically displayed via show or by using FoldingTrees.print_tree.

eye(Number, interactive = false)

Expand results

julia> eye(Number, interactive = false)
  DataType
├─ + : UnionAll Complex
└─   : DataType Real
   ├─   : DataType AbstractFloat
   │  ├─ + : DataType BigFloat
   │  ├─   : DataType Float16
   │  ├─   : DataType Float32
   │  └─   : DataType Float64
   ├─   : DataType AbstractIrrational
   │  └─ + : UnionAll Irrational
   ├─   : DataType Integer
   │  ├─   : DataType Bool
   │  ├─   : DataType Signed
   │  │  ├─ + : DataType BigInt
   │  │  ├─   : DataType Int128
   │  │  ├─   : DataType Int16
   │  │  ├─   : DataType Int32
   │  │  ├─   : DataType Int64
   │  │  └─   : DataType Int8
   │  └─   : DataType Unsigned
   │     ├─   : DataType UInt128
   │     ├─   : DataType UInt16
   │     ├─   : DataType UInt32
   │     ├─   : DataType UInt64
   │     └─   : DataType UInt8
   └─ + : UnionAll Rational

Summarize

Show a summary of arrays in a named tuple (also useful for DataFrames).

d = (a = rand(100), b = rand(100:200, 100), c = 4rand(Float32, 100))
eye(d)    # then hit `z` to summarize

Expand results

julia> eye(d)
[f] fields [d] docs [e] expand [m/M] methodswith [o] open [r] tree [s] show [t] typeof [z] summarize [q] quit
 >   : NamedTuple{(:a, :b, :c), Tuple{Vector{Float64}, Vector{Int64}, Vector{Float32}}}  (a = [0.721857, 0.174408, 0.897
 >      +  a: Vector{Float64} (100,) 800 x̄=0.535717, q=[0.0372074, 0.305533, 0.556568, 0.770658, 0.979569]
 >      +  b: Vector{Int64} (100,) 800 x̄=145.5, q=[100.0, 117.0, 145.5, 170.0, 200.0]
 >      +  c: Vector{Float32} (100,) 400 x̄=1.90419, q=[0.0898504, 1.09705, 1.9039, 2.68442, 3.93898]

API

By default, eye shows the properties of an object. That can be customized for different objects. For example, Dicts are shown with the key then the value, and abstract types are shown with subtypes. To customize what's shown for SomeType, define Eyeball.getobjects(x::SomeType). This method should return an iterator that returns a key and a value describing each of the child objects to be shown.

The display of objects can also be customized with the following boolean methods:

Eyeball.shouldrecurse(x)   
Eyeball.foldobject(x)   

shouldrecurse controls whether eye recurses into object x. This defaults to true. For overly large or complex objects, it helps to return false. That's done internally for Modules, Methods, and a few other types. foldobject controls whether eye automatically folds the object. This is useful for types where the components usually don't need to be shown. This defaults to false.

To add additional "summarize" options, define Base.show(io::IO, x::Eyeball.Summarize{T}) for type T.

Under the Hood

Eyeball uses FoldingTrees for display of trees and interactivity. This fork was extended to support customized key presses. TerminalPager is used for paging.

The code was adapted from InteractiveErrors.jl and Cthulhu.jl.

Download Details:

Author: tshort
Source Code: https://github.com/tshort/Eyeball.jl 
License: View license

#julia #object #type 

Eyeball.jl: Object and Type Viewer for Julia
Rupert  Beatty

Rupert Beatty

1667566380

Extensions Giving Swift's Codable API Type inference Super Powers

Codextended

Welcome to Codextended - a suite of extensions that aims to make Swift’s Codable API easier to use by giving it type inference-powered capabilities and conveniences. It’s not a wrapper, nor is it a brand new framework, instead it augments Codable directly in a very lightweight way.

Codable is awesome!

No third-party serialization framework can beat the convenience of Codable. Since it’s built in, it can both leverage the compiler to automatically synthesize all serialization code needed in many situations, and it can also be used as a common bridge between multiple different modules — without having to introduce any shared dependencies.

However, once some form of customization is needed — for example to transform parts of the decoded data, or to provide default values for certain keys — the standard Codable API starts to become really verbose. It also doesn’t take advantage of Swift’s robust type inference capabilities, which produces a lot of unnecessary boilerplate.

That’s what Codextended aims to fix.

Examples

Here are a few examples that demonstrate the difference between using “vanilla” Codable and the APIs that Codextended adds to it. The goal is to turn all common serialization operations into one-liners, rather than having to set up a ton of boilerplate.

🏢 Top-level API

Codextended makes a few slight tweaks to the top-level API used to encode and decode values, making it possible to leverage type inference and use methods on the actual values that are being encoded or decoded.

🍨 With vanilla Codable:

// Encoding
let encoder = JSONEncoder()
let data = try encoder.encode(value)

// Decoding
let decoder = JSONDecoder()
let article = try decoder.decode(Article.self, from: data)

🦸‍♀️ With Codextended:

// Encoding
let data = try value.encoded()

// Decoding
let article = try data.decoded() as Article

// Decoding when the type can be inferred
try saveArticle(data.decoded())

🔑 Overriding the behavior for a single key

While Codable is amazing as long as the serialized data’s format exactly matches the format of the Swift types that’ll use it — as soon as we need to make just a small tweak, things quickly go from really convenient to very verbose.

As an example, let’s just say that we want to provide a default value for one single property (without having to make it an optional, which would make it harder to handle in the rest of our code base). To do that, we need to completely manually implement our type’s decoding — like below for the tags property of an Article type.

🍨 With vanilla Codable:

struct Article: Codable {
    enum CodingKeys: CodingKey {
        case title
        case body
        case footnotes
        case tags
    }

    var title: String
    var body: String
    var footnotes: String?
    var tags: [String]

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        title = try container.decode(String.self, forKey: .title)
        body = try container.decode(String.self, forKey: .body)
        footnotes = try container.decodeIfPresent(String.self, forKey: .footnotes)
        tags = (try? container.decode([String].self, forKey: .tags)) ?? []
    }
}

🦸‍♂️ With Codextended:

struct Article: Codable {
    var title: String
    var body: String
    var footnotes: String?
    var tags: [String]

    init(from decoder: Decoder) throws {
        title = try decoder.decode("title")
        body = try decoder.decode("body")
        footnotes = try decoder.decodeIfPresent("footnotes")
        tags = (try? decoder.decode("tags")) ?? []
    }
}

Codextended includes decoding overloads both for CodingKey-based values and for string literals, so that we can pick the approach that’s the most appropriate/convenient for each given situation.

📆 Using date formatters

Codable already comes with support for custom date formats through assigning a DateFormatter to either a JSONEncoder or JSONDecoder. However, requiring each call site to be aware of the specific date formats used for each type isn’t always great — so with Codextended, it’s easy for a type itself to pick what date format it needs to use.

That’s really convenient when working with third-party data, and we only want to customize the date format for some of our types, or when we want to produce more readable date strings when encoding a value.

🍨 With vanilla Codable:

struct Bookmark: Codable {
    enum CodingKeys: CodingKey {
        case url
        case date
    }

    struct DateCodingError: Error {}

    static let dateFormatter = makeDateFormatter()

    var url: URL
    var date: Date

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        url = try container.decode(URL.self, forKey: .url)

        let dateString = try container.decode(String.self, forKey: .date)

        guard let date = Bookmark.dateFormatter.date(from: dateString) else {
            throw DateCodingError()
        }

        self.date = date
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(url, forKey: .url)

        let dateString = Bookmark.dateFormatter.string(from: date)
        try container.encode(dateString, forKey: .date)
    }
}

🦹‍♀️ With Codextended:

struct Bookmark: Codable {
    static let dateFormatter = makeDateFormatter()

    var url: URL
    var date: Date

    init(from decoder: Decoder) throws {
        url = try decoder.decode("url")
        date = try decoder.decode("date", using: Bookmark.dateFormatter)
    }

    func encode(to encoder: Encoder) throws {
        try encoder.encode(url, for: "url")
        try encoder.encode(date, for: "date", using: Bookmark.dateFormatter)
    }
}

Again, we could’ve chosen to use a CodingKeys enum above to represent our keys, rather than using inline strings.

Mix and match

Since Codextended is 100% implemented through extensions, you can easily mix and match it with “vanilla” Codable code within the same project. It also doesn’t change what makes Codable so great — the fact that it often doesn’t require any manual code at all, and that it can be used as a bridge between frameworks.

All it does is give Codable a helping hand when some form of customization is needed.

Installation

Since Codextended is implemented within a single file, the easiest way to use it is to simply drag and drop it into your Xcode project.

But if you wish to use a dependency manager, you can either use the Swift Package Manager by declaring Codextended as a dependency in your Package.swift file:

.package(url: "https://github.com/JohnSundell/Codextended", from: "0.1.0")

For more information, see the Swift Package Manager documentation.

You can also use CocoaPods by adding the following line to your Podfile:

pod "Codextended"

Contributions & support

Codextended is developed completely in the open, and your contributions are more than welcome.

Before you start using Codextended in any of your projects, it’s highly recommended that you spend a few minutes familiarizing yourself with its documentation and internal implementation (it all fits in a single file!), so that you’ll be ready to tackle any issues or edge cases that you might encounter.

To learn more about the principles used to implement Codextended, check out “Type inference-powered serialization in Swift” on Swift by Sundell.

This project does not come with GitHub Issues-based support, and users are instead encouraged to become active participants in its continued development — by fixing any bugs that they encounter, or improving the documentation wherever it’s found to be lacking.

If you wish to make a change, open a Pull Request — even if it just contains a draft of the changes you’re planning, or a test that reproduces an issue — and we can discuss it further from there.

Hope you’ll enjoy using Codextended! 😀

Download Details:

Author: JohnSundell
Source Code: https://github.com/JohnSundell/Codextended 
License: MIT license

#swift #type #json 

Extensions Giving Swift's Codable API Type inference Super Powers
Dexter  Goodwin

Dexter Goodwin

1667394180

Type-fest: A Collection Of Essential TypeScript Types

type-fest

A collection of essential TypeScript types

Many of the types here should have been built-in. You can help by suggesting some of them to the TypeScript project.

Either add this package as a dependency or copy-paste the needed types. No credit required. 👌

PR welcome for additional commonly needed types and docs improvements. Read the contributing guidelines first.

Help wanted with reviewing proposals and pull requests.

Install

npm install type-fest

Requires TypeScript >=4.7

Usage

import type {Except} from 'type-fest';

type Foo = {
	unicorn: string;
	rainbow: boolean;
};

type FooWithoutRainbow = Except<Foo, 'rainbow'>;
//=> {unicorn: string}

API

Click the type names for complete docs.

Basic

Utilities

  • EmptyObject - Represents a strictly empty plain object, the {} value.
  • IsEmptyObject - Returns a boolean for whether the type is strictly equal to an empty plain object, the {} value.
  • Except - Create a type from an object type without certain keys. This is a stricter version of Omit.
  • Writable - Create a type that strips readonly from all or some of an object's keys. The inverse of Readonly<T>.
  • Merge - Merge two types into a new type. Keys of the second type overrides keys of the first type.
  • MergeDeep - Merge two objects or two arrays/tuples recursively into a new type.
  • MergeExclusive - Create a type that has mutually exclusive keys.
  • RequireAtLeastOne - Create a type that requires at least one of the given keys.
  • RequireExactlyOne - Create a type that requires exactly a single key of the given keys and disallows more.
  • RequireAllOrNone - Create a type that requires all of the given keys or none of the given keys.
  • OmitIndexSignature - Omit any index signatures from the given object type, leaving only explicitly defined properties.
  • PickIndexSignature - Pick only index signatures from the given object type, leaving out all explicitly defined properties.
  • PartialDeep - Create a deeply optional version of another type. Use Partial<T> if you only need one level deep.
  • PartialOnUndefinedDeep - Create a deep version of another type where all keys accepting undefined type are set to optional.
  • ReadonlyDeep - Create a deeply immutable version of an object/Map/Set/Array type. Use Readonly<T> if you only need one level deep.
  • LiteralUnion - Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. Workaround for Microsoft/TypeScript#29729.
  • Opaque - Create an opaque type.
  • UnwrapOpaque - Revert an opaque type back to its original type.
  • InvariantOf - Create an invariant type, which is a type that does not accept supertypes and subtypes.
  • SetOptional - Create a type that makes the given keys optional.
  • SetRequired - Create a type that makes the given keys required.
  • SetNonNullable - Create a type that makes the given keys non-nullable.
  • ValueOf - Create a union of the given object's values, and optionally specify which keys to get the values from.
  • ConditionalKeys - Extract keys from a shape where values extend the given Condition type.
  • ConditionalPick - Like Pick except it selects properties from a shape where the values extend the given Condition type.
  • ConditionalPickDeep - Like ConditionalPick except that it selects the properties deeply.
  • ConditionalExcept - Like Omit except it removes properties from a shape where the values extend the given Condition type.
  • UnionToIntersection - Convert a union type to an intersection type.
  • LiteralToPrimitive - Convert a literal type to the primitive type it belongs to.
  • Stringified - Create a type with the keys of the given type changed to string type.
  • IterableElement - Get the element type of an Iterable/AsyncIterable. For example, an array or a generator.
  • Entry - Create a type that represents the type of an entry of a collection.
  • Entries - Create a type that represents the type of the entries of a collection.
  • SetReturnType - Create a function type with a return type of your choice and the same parameters as the given function type.
  • Simplify - Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.
  • Get - Get a deeply-nested property from an object using a key path, like Lodash's .get() function.
  • StringKeyOf - Get keys of the given type as strings.
  • Schema - Create a deep version of another object type where property values are recursively replaced into a given value type.
  • Exact - Create a type that does not allow extra properties.
  • OptionalKeysOf - Extract all optional keys from the given type.
  • HasOptionalKeys - Create a true/false type depending on whether the given type has any optional fields.
  • RequiredKeysOf - Extract all required keys from the given type.
  • HasRequiredKeys - Create a true/false type depending on whether the given type has any required fields.
  • Spread - Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.

JSON

Async

  • Promisable - Create a type that represents either the value or the value wrapped in PromiseLike.
  • AsyncReturnType - Unwrap the return type of a function that returns a Promise.
  • Asyncify - Create an async version of the given function type.

String

  • Trim - Remove leading and trailing spaces from a string.
  • Split - Represents an array of strings split using a given character or character set.
  • Replace - Represents a string with some or all matches replaced by a replacement.

Array

  • Includes - Returns a boolean for whether the given array includes the given item.
  • Join - Join an array of strings and/or numbers using the given string as a delimiter.
  • LastArrayElement - Extracts the type of the last element of an array.
  • FixedLengthArray - Create a type that represents an array of the given type and length.
  • MultidimensionalArray - Create a type that represents a multidimensional array of the given type and dimensions.
  • MultidimensionalReadonlyArray - Create a type that represents a multidimensional readonly array of the given type and dimensions.
  • ReadonlyTuple - Create a type that represents a read-only tuple of the given type and length.
  • TupleToUnion - Convert a tuple into a union type of its elements.

Numeric

Change case

Miscellaneous

Declined types

If we decline a type addition, we will make sure to document the better solution here.

  • Diff and Spread - The pull request author didn't provide any real-world use-cases and the PR went stale. If you think this type is useful, provide some real-world use-cases and we might reconsider.
  • Dictionary - You only save a few characters (Dictionary<number> vs Record<string, number>) from Record, which is more flexible and well-known. Also, you shouldn't use an object as a dictionary. We have Map in JavaScript now.
  • ExtractProperties and ExtractMethods - The types violate the single responsibility principle. Instead, refine your types into more granular type hierarchies.
  • Url2Json - Inferring search parameters from a URL string is a cute idea, but not very useful in practice, since search parameters are usually dynamic and defined separately.
  • Nullish - The type only saves a couple of characters, not everyone knows what "nullish" means, and I'm also trying to get away from null.
  • TitleCase - It's not solving a common need and is a better fit for a separate package.
  • ExtendOr and ExtendAnd - The benefits don't outweigh having to learn what they mean.
  • PackageJsonExtras - There are too many possible configurations that can be put into package.json. If you would like to extend PackageJson to support an additional configuration in your project, please see the Extending existing types section below.

Alternative type names

If you know one of our types by a different name, add it here for discovery.

Tips

Extending existing types

PackageJson - There are a lot of tools that place extra configurations inside the package.json file. You can extend PackageJson to support these additional configurations.

Example

Playground

import type {PackageJson as BasePackageJson} from 'type-fest';
 import type {Linter} from 'eslint';

 type PackageJson = BasePackageJson & {eslintConfig?: Linter.Config};

Related

Built-in types

There are many advanced types most users don't know about.

Partial<T> - Make all properties in T optional.

Example

Playground

 interface NodeConfig {
 		appName: string;
 		port: number;
 }

 class NodeAppBuilder {
 		private configuration: NodeConfig = {
 				appName: 'NodeApp',
 				port: 3000
 		};

 		private updateConfig<Key extends keyof NodeConfig>(key: Key, value: NodeConfig[Key]) {
 				this.configuration[key] = value;
 		}

 		config(config: Partial<NodeConfig>) {
 				type NodeConfigKey = keyof NodeConfig;

 				for (const key of Object.keys(config) as NodeConfigKey[]) {
 						const updateValue = config[key];

 						if (updateValue === undefined) {
 								continue;
 						}

 						this.updateConfig(key, updateValue);
 				}

 				return this;
 		}
 }

 // `Partial<NodeConfig>`` allows us to provide only a part of the
 // NodeConfig interface.
 new NodeAppBuilder().config({appName: 'ToDoApp'});

Required<T> - Make all properties in T required.

Example

Playground

 interface ContactForm {
 		email?: string;
 		message?: string;
 }

 function submitContactForm(formData: Required<ContactForm>) {
 		// Send the form data to the server.
 }

 submitContactForm({
 		email: 'ex@mple.com',
 		message: 'Hi! Could you tell me more about…',
 });

 // TypeScript error: missing property 'message'
 submitContactForm({
 		email: 'ex@mple.com',
 });

Readonly<T> - Make all properties in T readonly.

Example

Playground

 enum LogLevel {
 		Off,
 		Debug,
 		Error,
 		Fatal
 };

 interface LoggerConfig {
 		name: string;
 		level: LogLevel;
 }

 class Logger {
 		config: Readonly<LoggerConfig>;

 		constructor({name, level}: LoggerConfig) {
 				this.config = {name, level};
 				Object.freeze(this.config);
 		}
 }

 const config: LoggerConfig = {
 	name: 'MyApp',
 	level: LogLevel.Debug
 };

 const logger = new Logger(config);

 // TypeScript Error: cannot assign to read-only property.
 logger.config.level = LogLevel.Error;

 // We are able to edit config variable as we please.
 config.level = LogLevel.Error;

Pick<T, K> - From T, pick a set of properties whose keys are in the union K.

Example

Playground

 interface Article {
 		title: string;
 		thumbnail: string;
 		content: string;
 }

 // Creates new type out of the `Article` interface composed
 // from the Articles' two properties: `title` and `thumbnail`.
 // `ArticlePreview = {title: string; thumbnail: string}`
 type ArticlePreview = Pick<Article, 'title' | 'thumbnail'>;

 // Render a list of articles using only title and description.
 function renderArticlePreviews(previews: ArticlePreview[]): HTMLElement {
 		const articles = document.createElement('div');

 		for (const preview of previews) {
 				// Append preview to the articles.
 		}

 		return articles;
 }

 const articles = renderArticlePreviews([
 		{
 			title: 'TypeScript tutorial!',
 			thumbnail: '/assets/ts.jpg'
 		}
 ]);

Record<K, T> - Construct a type with a set of properties K of type T.

Example

Playground

 // Positions of employees in our company.
 type MemberPosition = 'intern' | 'developer' | 'tech-lead';

 // Interface describing properties of a single employee.
 interface Employee {
 		firstName: string;
 		lastName: string;
 		yearsOfExperience: number;
 }

 // Create an object that has all possible `MemberPosition` values set as keys.
 // Those keys will store a collection of Employees of the same position.
 const team: Record<MemberPosition, Employee[]> = {
 		intern: [],
 		developer: [],
 		'tech-lead': [],
 };

 // Our team has decided to help John with his dream of becoming Software Developer.
 team.intern.push({
 	firstName: 'John',
 	lastName: 'Doe',
 	yearsOfExperience: 0
 });

 // `Record` forces you to initialize all of the property keys.
 // TypeScript Error: "tech-lead" property is missing
 const teamEmpty: Record<MemberPosition, null> = {
 		intern: null,
 		developer: null,
 };

Exclude<T, U> - Exclude from T those types that are assignable to U.

Example

Playground

 interface ServerConfig {
 	port: null | string | number;
 }

 type RequestHandler = (request: Request, response: Response) => void;

 // Exclude `null` type from `null | string | number`.
 // In case the port is equal to `null`, we will use default value.
 function getPortValue(port: Exclude<ServerConfig['port'], null>): number {
 	if (typeof port === 'string') {
 		return parseInt(port, 10);
 	}

 	return port;
 }

 function startServer(handler: RequestHandler, config: ServerConfig): void {
 	const server = require('http').createServer(handler);

 	const port = config.port === null ? 3000 : getPortValue(config.port);
 	server.listen(port);
 }

Extract<T, U> - Extract from T those types that are assignable to U.

Example

Playground

 declare function uniqueId(): number;

 const ID = Symbol('ID');

 interface Person {
 	[ID]: number;
 	name: string;
 	age: number;
 }

 // Allows changing the person data as long as the property key is of string type.
 function changePersonData<
 	Obj extends Person,
 	Key extends Extract<keyof Person, string>,
 	Value extends Obj[Key]
 > (obj: Obj, key: Key, value: Value): void {
 	obj[key] = value;
 }

 // Tiny Andrew was born.
 const andrew = {
 	[ID]: uniqueId(),
 	name: 'Andrew',
 	age: 0,
 };

 // Cool, we're fine with that.
 changePersonData(andrew, 'name', 'Pony');

 // Goverment didn't like the fact that you wanted to change your identity.
 changePersonData(andrew, ID, uniqueId());

NonNullable<T> - Exclude null and undefined from T.

ExampleWorks with strictNullChecks set to true.

Playground

 type PortNumber = string | number | null;

 /** Part of a class definition that is used to build a server */
 class ServerBuilder {
 		portNumber!: NonNullable<PortNumber>;

 		port(this: ServerBuilder, port: PortNumber): ServerBuilder {
 				if (port == null) {
 						this.portNumber = 8000;
 				} else {
 						this.portNumber = port;
 				}

 				return this;
 		}
 }

 const serverBuilder = new ServerBuilder();

 serverBuilder
 		.port('8000')   // portNumber = '8000'
 		.port(null)     // portNumber =  8000
 		.port(3000);    // portNumber =  3000

 // TypeScript error
 serverBuilder.portNumber = null;

Parameters<T> - Obtain the parameters of a function type in a tuple.

Example

Playground

 function shuffle(input: any[]): void {
 	// Mutate array randomly changing its' elements indexes.
 }

 function callNTimes<Fn extends (...args: any[]) => any> (func: Fn, callCount: number) {
 	// Type that represents the type of the received function parameters.
 	type FunctionParameters = Parameters<Fn>;

 	return function (...args: FunctionParameters) {
 		for (let i = 0; i < callCount; i++) {
 			func(...args);
 		}
 	}
 }

 const shuffleTwice = callNTimes(shuffle, 2);

ConstructorParameters<T> - Obtain the parameters of a constructor function type in a tuple.

Example

Playground

 class ArticleModel {
 	title: string;
 	content?: string;

 	constructor(title: string) {
 		this.title = title;
 	}
 }

 class InstanceCache<T extends (new (...args: any[]) => any)> {
 	private ClassConstructor: T;
 	private cache: Map<string, InstanceType<T>> = new Map();

 	constructor (ctr: T) {
 		this.ClassConstructor = ctr;
 	}

 	getInstance (...args: ConstructorParameters<T>): InstanceType<T> {
 		const hash = this.calculateArgumentsHash(...args);

 		const existingInstance = this.cache.get(hash);
 		if (existingInstance !== undefined) {
 			return existingInstance;
 		}

 		return new this.ClassConstructor(...args);
 	}

 	private calculateArgumentsHash(...args: any[]): string {
 		// Calculate hash.
 		return 'hash';
 	}
 }

 const articleCache = new InstanceCache(ArticleModel);
 const amazonArticle = articleCache.getInstance('Amazon forests burining!');

ReturnType<T> - Obtain the return type of a function type.

Example

Playground

 /** Provides every element of the iterable `iter` into the `callback` function and stores the results in an array. */
 function mapIter<
 		Elem,
 		Func extends (elem: Elem) => any,
 		Ret extends ReturnType<Func>
 >(iter: Iterable<Elem>, callback: Func): Ret[] {
 		const mapped: Ret[] = [];

 		for (const elem of iter) {
 				mapped.push(callback(elem));
 		}

 		return mapped;
 }

 const setObject: Set<string> = new Set();
 const mapObject: Map<number, string> = new Map();

 mapIter(setObject, (value: string) => value.indexOf('Foo')); // number[]

 mapIter(mapObject, ([key, value]: [number, string]) => {
 		return key % 2 === 0 ? value : 'Odd';
 }); // string[]

InstanceType<T> - Obtain the instance type of a constructor function type.

Example

Playground

 class IdleService {
 		doNothing (): void {}
 }

 class News {
 		title: string;
 		content: string;

 		constructor(title: string, content: string) {
 				this.title = title;
 				this.content = content;
 		}
 }

 const instanceCounter: Map<Function, number> = new Map();

 interface Constructor {
 		new(...args: any[]): any;
 }

 // Keep track how many instances of `Constr` constructor have been created.
 function getInstance<
 		Constr extends Constructor,
 		Args extends ConstructorParameters<Constr>
 >(constructor: Constr, ...args: Args): InstanceType<Constr> {
 		let count = instanceCounter.get(constructor) || 0;

 		const instance = new constructor(...args);

 		instanceCounter.set(constructor, count + 1);

 		console.log(`Created ${count + 1} instances of ${Constr.name} class`);

 		return instance;
 }


 const idleService = getInstance(IdleService);
 // Will log: `Created 1 instances of IdleService class`
 const newsEntry = getInstance(News, 'New ECMAScript proposals!', 'Last month...');
 // Will log: `Created 1 instances of News class`

Omit<T, K> - Constructs a type by picking all properties from T and then removing K.

Example

Playground

 interface Animal {
 		imageUrl: string;
 		species: string;
 		images: string[];
 		paragraphs: string[];
 }

 // Creates new type with all properties of the `Animal` interface
 // except 'images' and 'paragraphs' properties. We can use this
 // type to render small hover tooltip for a wiki entry list.
 type AnimalShortInfo = Omit<Animal, 'images' | 'paragraphs'>;

 function renderAnimalHoverInfo (animals: AnimalShortInfo[]): HTMLElement {
 		const container = document.createElement('div');
 		// Internal implementation.
 		return container;
 }

Uppercase<S extends string> - Transforms every character in a string into uppercase.

Example

 type T = Uppercase<'hello'>;  // 'HELLO'

 type T2 = Uppercase<'foo' | 'bar'>;  // 'FOO' | 'BAR'

 type T3<S extends string> = Uppercase<`aB${S}`>;
 type T4 = T3<'xYz'>;  // 'ABXYZ'

 type T5 = Uppercase<string>;  // string
 type T6 = Uppercase<any>;  // any
 type T7 = Uppercase<never>;  // never
 type T8 = Uppercase<42>;  // Error, type 'number' does not satisfy the constraint 'string'

Lowercase<S extends string> - Transforms every character in a string into lowercase.

Example

 type T = Lowercase<'HELLO'>;  // 'hello'

 type T2 = Lowercase<'FOO' | 'BAR'>;  // 'foo' | 'bar'

 type T3<S extends string> = Lowercase<`aB${S}`>;
 type T4 = T3<'xYz'>;  // 'abxyz'

 type T5 = Lowercase<string>;  // string
 type T6 = Lowercase<any>;  // any
 type T7 = Lowercase<never>;  // never
 type T8 = Lowercase<42>;  // Error, type 'number' does not satisfy the constraint 'string'

Capitalize<S extends string> - Transforms the first character in a string into uppercase.

Example

 type T = Capitalize<'hello'>;  // 'Hello'

 type T2 = Capitalize<'foo' | 'bar'>;  // 'Foo' | 'Bar'

 type T3<S extends string> = Capitalize<`aB${S}`>;
 type T4 = T3<'xYz'>;  // 'ABxYz'

 type T5 = Capitalize<string>;  // string
 type T6 = Capitalize<any>;  // any
 type T7 = Capitalize<never>;  // never
 type T8 = Capitalize<42>;  // Error, type 'number' does not satisfy the constraint 'string'

Uncapitalize<S extends string> - Transforms the first character in a string into lowercase.

  • Example
 type T = Uncapitalize<'Hello'>;  // 'hello'

 type T2 = Uncapitalize<'Foo' | 'Bar'>;  // 'foo' | 'bar'

 type T3<S extends string> = Uncapitalize<`AB${S}`>;
 type T4 = T3<'xYz'>;  // 'aBxYz'

 type T5 = Uncapitalize<string>;  // string
 type T6 = Uncapitalize<any>;  // any
 type T7 = Uncapitalize<never>;  // never
 type T8 = Uncapitalize<42>;  // Error, type 'number' does not satisfy the constraint 'string'

You can find some examples in the TypeScript docs.

Maintainers

Download Details:

Author: Sindresorhus
Source Code: https://github.com/sindresorhus/type-fest 
License: CC0-1.0, MIT licenses found

#typescript #utilities #type 

Type-fest: A Collection Of Essential TypeScript Types
Reid  Rohan

Reid Rohan

1667030460

Collection Of TypeScript Type Challenges with online Judge

Type-challenges

Collection of TypeScript type challenges

English | 简体中文 | 日本語 | 한국어

Intro

by the power of TypeScript's well-known Turing Completed type system

High-quality types can help improve projects' maintainability while avoiding potential bugs.

There are a bunch of awesome type utility libraries that may boost your works on types, like ts-toolbelt, utility-types, SimplyTyped, etc., which you can already use.

This project is aimed at helping you better understand how the type system works, writing your own utilities, or just having fun with the challenges. We are also trying to form a community where you can ask questions and get answers you have faced in the real world - they may become part of the challenges!

Challenges

Click the following badges to see details of the challenges.

By Plain Text
 

warm-up (1)

easy (13)

medium (72)

hard (40)

extreme (14)

Upcoming challenges

🔥 Start the challenge in TypeScript Playground

⚡️ Start the challenge in VS Code

Recommended Readings

Official

The TypeScript Handbook

The New Handbook

Articles

Talks

Projects / Solutions

Books

TODO

How to Contribute

There are several ways you can contribute to this project

  • Share your answers / solutions
  • Propose new challenges
  • Add more test cases to the existing challenges
  • Provide learning resources or ideas of how to solve challenges
  • Share the problems you have faced in real-world projects, regardless you having the solution or not - the community would help you as well
  • Help with others by discussion in issues
  • Contribute the infra of this project TODOs.md

Just open an issue and choose the corresponding template. Thanks!

Thanks

This project was born from solving real-world types problem with @hardfist and @MeCKodo. And great thanks to @sinoon who contributed a lot while giving early feedback on this project.

Inspired by

Download Details:

Author: Type-challenges
Source Code: https://github.com/type-challenges/type-challenges 
License: MIT license

#typescript #challenge #type 

Collection Of TypeScript Type Challenges with online Judge

A Julia Type for Representing Square Roots Of Rational Numbers

RationalRoots

This package provides a data type RationalRoot{T<:Integer} to exactly represent the (positive or negative) square root of a rational number of type Rational{T}.

Basic usage

RationalRoots can be created from any other real number type by using constructors or convert; if the input is not an integer or rational (i.e. a floating point number), the function rationalize from Julia Base is used to first approximate it by a rational number.

julia> RationalRoot(-2.5)
-√(25//4)

julia> convert(RationalRoot{Int16}, 7//2)
+√(49//4)

julia> RationalRoot{BigInt}(2)
+√(4//1)

Another way of creating a RationalRoot is using the signedroot function, which maps a real number x to sign(x)*sqrt(abs(x)) = x/sqrt(abs(x)). If x is an Integer or Rational, the result is represented as a RationalRoot type. For a floating point number, signedroot will return a floating point number. A RationalRoot output can be forced by using signedroot(<:RationalRoot, x), in which case rationalize is to rationalize the result.

julia> signedroot(3)
+√(3//1)

julia> signedroot(-4.0)
-2.0

julia> signedroot(RationalRoot, 5.2)
+√(26//5)

julia> signedroot(RationalRoot{Int8}, 8)
+√(8//1)

There is also the inverse function signedsquare, which maps a number x to sign(x)*x^2 = x*abs(x).

julia> signedsquare(1.5)
2.25

julia> signedsquare(-2//3)
-4//9

julia> signedsquare(RationalRoot{BigInt}(1.5))
9//4

julia> typeof(ans)
Rational{BigInt}

The type RationalRoot will be maintained under multiplication and division with itself or with number of type Integer and Rational. Addition and subtraction require that the type is converted to a floating point number.

Download Details:

Author: Jutho
Source Code: https://github.com/Jutho/RationalRoots.jl 
License: View license

#julia #type #number 

A Julia Type for Representing Square Roots Of Rational Numbers

BFloat16s.jl: Nobody Needed All Those Bits anyway

BFloat16s

This package defines the BFloat16 data type. The only currently available hardware implementation of this datatype are Google's Cloud TPUs. As such, this package is suitable to evaluate whether using TPUs would cause precision problems for any particular algorithm, even without access to TPU hardware. Note that this package is designed for functionality, not performance, so this package should be used for precision experiments only, not performance experiments.

Usage

This package exports the BFloat16 data type. This datatype should behave just like any builtin floating point type (e.g. you can construct it from other floating point types - e.g. BFloat16(1.0)). In addition, this package provides the LowPrecArray type. This array is supposed to emulate the kind of matmul operation that TPUs do well (BFloat16 multiply with Float32 accumulate). Broadcasts and scalar operations are peformed in Float32 (as they would be on a TPU) while matrix multiplies are performed in BFloat16 with Float32 accumulates, e.g.

julia> A = LowPrecArray(rand(Float32, 5, 5))
5×5 LowPrecArray{2,Array{Float32,2}}:
 0.252818  0.619702   0.553199  0.75225   0.30819
 0.166347  0.976339   0.399945  0.589101  0.526253
 0.350232  0.0447034  0.490874  0.525144  0.841436
 0.903734  0.879541   0.706704  0.304369  0.951702
 0.308417  0.645731   0.65906   0.636451  0.765263

julia> A^2
5×5 LowPrecArray{2,Array{Float32,2}}:
 1.13603   1.64932  1.39712  1.27283  1.82597
 1.03891   1.93298  1.44455  1.42625  1.86842
 0.998384  1.28403  1.37666  1.24076  1.68507
 1.18951   2.33245  2.04367  2.26849  2.35588
 1.22636   1.90367  1.70848  1.63986  2.1826

julia> A.storage^2
5×5 Array{Float32,2}:
 1.13564  1.64708  1.39399  1.27087  1.82128
 1.03924  1.93216  1.44198  1.42456  1.86497
 1.00201  1.28786  1.37826  1.24295  1.6882
 1.19089  2.33262  2.04094  2.26745  2.354
 1.22742  1.90498  1.70653  1.63928  2.18076

julia> Float64.(A.storage)^2
5×5 Array{Float64,2}:
 1.13564  1.64708  1.39399  1.27087  1.82128
 1.03924  1.93216  1.44198  1.42456  1.86497
 1.00201  1.28786  1.37826  1.24295  1.6882
 1.19089  2.33262  2.04094  2.26745  2.354
 1.22742  1.90498  1.70653  1.63928  2.18076

Note that the low precision result differs from (is less precise than) the result computed in Float32 arithmetic (which matches the result in Float64 precision).

Download Details:

Author: JuliaMath
Source Code: https://github.com/JuliaMath/BFloat16s.jl 
License: View license

#julia #data #type 

BFloat16s.jl: Nobody Needed All Those Bits anyway

Types and Functions for Working with Continued Fractions in Julia

ContinuedFractions.jl

Usage

julia> using ContinuedFractions

julia> cf = ContinuedFraction(sqrt(2))
ContinuedFraction{Int64}([1,2,2,2,2,2,2,2,2,2  …  2,2,2,2,2,2,2,2,2,3])

julia> collect(convergents(cf))
22-element Array{Rational{Int64},1}:
        0//1
        1//1
        3//2
        7//5
       17//12
       41//29
       99//70
      239//169
      577//408
     1393//985
         ⋮
    47321//33461
   114243//80782
   275807//195025
   665857//470832
  1607521//1136689
  3880899//2744210
  9369319//6625109
 22619537//15994428
 77227930//54608393

For additional significant digits you can use BigInt / BigFloat.

julia> cf = ContinuedFraction(sqrt(big(2)))
julia> collect(convergents(cf))

101-element Array{Rational{BigInt},1}:
                                       1//1                                      
                                       3//2                                      
                                       7//5                                      
                                      17//12                                     
                                      41//29                                     
                                      99//70                                     
                                     239//169                                    
                                     577//408                                    
                                    1393//985                                    
                                    3363//2378                                   
                                    8119//5741                                   
                                   19601//13860                                  
                                   47321//33461                                  
                                        ⋮                                        
     14085805418356991727446091676022499//9960168529794442859224531878561050     
     34006142477945877445895155433144599//24045973948151434586670623554583549    
     82098090374248746619236402542311697//58052116426097312032565778987728148    
    198202323226443370684367960517767993//140150206800346058651802181530039845   
    478502736827135487987972323577847683//338352530026789429336170142047807838   
   1155207796880714346660312607673463359//816855266853924917324142465625655521   
   2788918330588564181308597538924774401//1972063063734639263984455073299118880  
   6733044458057842709277507685523012161//4760981394323203445293052612223893281  
  16255007246704249599863612909970798723//11494025852381046154570560297746905442 
  39243058951466341909004733505464609607//27749033099085295754434173207717704165 
  94741125149636933417873079920900017937//66992092050551637663438906713182313772 
 228725309250740208744750893347264645481//161733217200188571081311986634082331709

Download Details:

Author: johnmyleswhite
Source Code: https://github.com/johnmyleswhite/ContinuedFractions.jl 
License: View license

#julia #type #functions 

Types and Functions for Working with Continued Fractions in Julia
Reid  Rohan

Reid Rohan

1665083520

File-type-cli: Detect The File Type Of A File Or Stdin

file-type-cli

Detect the file type of a file or stdin

Install

npm install --global file-type-cli

Usage

$ file-type --help

  Usage
    $ file-type <filename>
    $ file-type < <filename>

  Example
    $ file-type unicorn.png
    png
    image/png

Supported file types

Related

Download Details:

Author: Sindresorhus
Source Code: https://github.com/sindresorhus/file-type-cli 
License: MIT license

#javascript #node #cli #type 

File-type-cli: Detect The File Type Of A File Or Stdin
Reid  Rohan

Reid Rohan

1665079680

File-type: Detect The File Type Of A Buffer/Uint8Array/ArrayBuffer

file-type

Detect the file type of a Buffer/Uint8Array/ArrayBuffer

The file type is detected by checking the magic number of the buffer.

This package is for detecting binary-based file formats, not text-based formats like .txt, .csv, .svg, etc.

We accept contributions for commonly used modern file formats, not historical or obscure ones. Open an issue first for discussion.

Install

npm install file-type

This package is a ESM package. Your project needs to be ESM too. Read more.

If you use it with Webpack, you need the latest Webpack version and ensure you configure it correctly for ESM.

Usage

Node.js

Determine file type from a file:

import {fileTypeFromFile} from 'file-type';

console.log(await fileTypeFromFile('Unicorn.png'));
//=> {ext: 'png', mime: 'image/png'}

Determine file type from a Buffer, which may be a portion of the beginning of a file:

import {fileTypeFromBuffer} from 'file-type';
import {readChunk} from 'read-chunk';

const buffer = await readChunk('Unicorn.png', {length: 4100});

console.log(await fileTypeFromBuffer(buffer));
//=> {ext: 'png', mime: 'image/png'}

Determine file type from a stream:

import fs from 'node:fs';
import {fileTypeFromStream} from 'file-type';

const stream = fs.createReadStream('Unicorn.mp4');

console.log(await fileTypeFromStream(stream));
//=> {ext: 'mp4', mime: 'video/mp4'}

The stream method can also be used to read from a remote location:

import got from 'got';
import {fileTypeFromStream} from 'file-type';

const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';

const stream = got.stream(url);

console.log(await fileTypeFromStream(stream));
//=> {ext: 'jpg', mime: 'image/jpeg'}

Another stream example:

import stream from 'node:stream';
import fs from 'node:fs';
import crypto from 'node:crypto';
import {fileTypeStream} from 'file-type';

const read = fs.createReadStream('encrypted.enc');
const decipher = crypto.createDecipheriv(alg, key, iv);

const streamWithFileType = await fileTypeStream(stream.pipeline(read, decipher));

console.log(streamWithFileType.fileType);
//=> {ext: 'mov', mime: 'video/quicktime'}

const write = fs.createWriteStream(`decrypted.${streamWithFileType.fileType.ext}`);
streamWithFileType.pipe(write);

Browser

import {fileTypeFromStream} from 'file-type';

const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';

const response = await fetch(url);
const fileType = await fileTypeFromStream(response.body);

console.log(fileType);
//=> {ext: 'jpg', mime: 'image/jpeg'}

API

fileTypeFromBuffer(buffer)

Detect the file type of a Buffer, Uint8Array, or ArrayBuffer.

The file type is detected by checking the magic number of the buffer.

If file access is available, it is recommended to use fileTypeFromFile() instead.

Returns a Promise for an object with the detected file type and MIME type:

Or undefined when there is no match.

buffer

Type: Buffer | Uint8Array | ArrayBuffer

A buffer representing file data. It works best if the buffer contains the entire file, it may work with a smaller portion as well.

fileTypeFromFile(filePath)

Detect the file type of a file path.

The file type is detected by checking the magic number of the buffer.

Returns a Promise for an object with the detected file type and MIME type:

Or undefined when there is no match.

filePath

Type: string

The file path to parse.

fileTypeFromStream(stream)

Detect the file type of a Node.js readable stream.

The file type is detected by checking the magic number of the buffer.

Returns a Promise for an object with the detected file type and MIME type:

Or undefined when there is no match.

stream

Type: stream.Readable

A readable stream representing file data.

fileTypeFromBlob(blob)

Detect the file type of a Blob.

Note: This method is only available in the browser.

The file type is detected by checking the magic number of the buffer.

Returns a Promise for an object with the detected file type and MIME type:

Or undefined when there is no match.

import {fileTypeFromBlob} from 'file-type';

const blob = new Blob(['<?xml version="1.0" encoding="ISO-8859-1" ?>'], {
	type: 'plain/text',
	endings: 'native'
});

console.log(await fileTypeFromBlob(blob));
//=> {ext: 'txt', mime: 'plain/text'}

fileTypeFromTokenizer(tokenizer)

Detect the file type from an ITokenizer source.

This method is used internally, but can also be used for a special "tokenizer" reader.

A tokenizer propagates the internal read functions, allowing alternative transport mechanisms, to access files, to be implemented and used.

Returns a Promise for an object with the detected file type and MIME type:

Or undefined when there is no match.

An example is @tokenizer/http, which requests data using HTTP-range-requests. A difference with a conventional stream and the tokenizer, is that it can ignore (seek, fast-forward) in the stream. For example, you may only need and read the first 6 bytes, and the last 128 bytes, which may be an advantage in case reading the entire file would take longer.

import {makeTokenizer} from '@tokenizer/http';
import {fileTypeFromTokenizer} from 'file-type';

const audioTrackUrl = 'https://test-audio.netlify.com/Various%20Artists%20-%202009%20-%20netBloc%20Vol%2024_%20tiuqottigeloot%20%5BMP3-V2%5D/01%20-%20Diablo%20Swing%20Orchestra%20-%20Heroines.mp3';

const httpTokenizer = await makeTokenizer(audioTrackUrl);
const fileType = await fileTypeFromTokenizer(httpTokenizer);

console.log(fileType);
//=> {ext: 'mp3', mime: 'audio/mpeg'}

Or use @tokenizer/s3 to determine the file type of a file stored on Amazon S3:

import S3 from 'aws-sdk/clients/s3';
import {makeTokenizer} from '@tokenizer/s3';
import {fileTypeFromTokenizer} from 'file-type';

// Initialize the S3 client
const s3 = new S3();

// Initialize the S3 tokenizer.
const s3Tokenizer = await makeTokenizer(s3, {
	Bucket: 'affectlab',
	Key: '1min_35sec.mp4'
});

// Figure out what kind of file it is.
const fileType = await fileTypeFromTokenizer(s3Tokenizer);
console.log(fileType);

Note that only the minimum amount of data required to determine the file type is read (okay, just a bit extra to prevent too many fragmented reads).

tokenizer

Type: ITokenizer

A file source implementing the tokenizer interface.

fileTypeStream(readableStream, options?)

Returns a Promise which resolves to the original readable stream argument, but with an added fileType property, which is an object like the one returned from fileTypeFromFile().

This method can be handy to put in between a stream, but it comes with a price. Internally stream() builds up a buffer of sampleSize bytes, used as a sample, to determine the file type. The sample size impacts the file detection resolution. A smaller sample size will result in lower probability of the best file type detection.

Note: This method is only available when using Node.js. Note: Requires Node.js 14 or later.

readableStream

Type: stream.Readable

options

Type: object

sampleSize

Type: number
Default: 4100

The sample size in bytes.

Example

import got from 'got';
import {fileTypeStream} from 'file-type';

const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';

const stream1 = got.stream(url);
const stream2 = await fileTypeStream(stream1, {sampleSize: 1024});

if (stream2.fileType?.mime === 'image/jpeg') {
	// stream2 can be used to stream the JPEG image (from the very beginning of the stream)
}

readableStream

Type: stream.Readable

The input stream.

supportedExtensions

Returns a Set<string> of supported file extensions.

supportedMimeTypes

Returns a Set<string> of supported MIME types.

Supported file types

  • 3g2 - Multimedia container format defined by the 3GPP2 for 3G CDMA2000 multimedia services
  • 3gp - Multimedia container format defined by the Third Generation Partnership Project (3GPP) for 3G UMTS multimedia services
  • 3mf - 3D Manufacturing Format
  • 7z - 7-Zip archive
  • Z - Unix Compressed File
  • aac - Advanced Audio Coding
  • ac3 - ATSC A/52 Audio File
  • ai - Adobe Illustrator Artwork
  • aif - Audio Interchange file
  • alias - macOS Alias file
  • amr - Adaptive Multi-Rate audio codec
  • ape - Monkey's Audio
  • apng - Animated Portable Network Graphics
  • ar - Archive file
  • arrow - Columnar format for tables of data
  • arw - Sony Alpha Raw image file
  • asar - Archive format primarily used to enclose Electron applications
  • asf - Advanced Systems Format
  • avi - Audio Video Interleave file
  • avif - AV1 Image File Format
  • blend - Blender project
  • bmp - Bitmap image file
  • bpg - Better Portable Graphics file
  • bz2 - Archive file
  • cab - Cabinet file
  • cfb - Compount File Binary Format
  • chm - Microsoft Compiled HTML Help
  • cr2 - Canon Raw image file (v2)
  • cr3 - Canon Raw image file (v3)
  • crx - Google Chrome extension
  • cur - Icon file
  • dcm - DICOM Image File
  • deb - Debian package
  • dmg - Apple Disk Image
  • dng - Adobe Digital Negative image file
  • docx - Microsoft Word
  • dsf - Sony DSD Stream File (DSF)
  • elf - Unix Executable and Linkable Format
  • eot - Embedded OpenType font
  • eps - Encapsulated PostScript
  • epub - E-book file
  • exe - Executable file
  • f4a - Audio-only ISO base media file format used by Adobe Flash Player
  • f4b - Audiobook and podcast ISO base media file format used by Adobe Flash Player
  • f4p - ISO base media file format protected by Adobe Access DRM used by Adobe Flash Player
  • f4v - ISO base media file format used by Adobe Flash Player
  • flac - Free Lossless Audio Codec
  • flif - Free Lossless Image Format
  • flv - Flash video
  • gif - Graphics Interchange Format
  • glb - GL Transmission Format
  • gz - Archive file
  • heic - High Efficiency Image File Format
  • icns - Apple Icon image
  • ico - Windows icon file
  • ics - iCalendar
  • indd - Adobe InDesign document
  • it - Audio module format: Impulse Tracker
  • jp2 - JPEG 2000
  • jpg - Joint Photographic Experts Group image
  • jpm - JPEG 2000
  • jpx - JPEG 2000
  • jxl - JPEG XL image format
  • jxr - Joint Photographic Experts Group extended range
  • ktx - OpenGL and OpenGL ES textures
  • lnk - Microsoft Windows file shortcut
  • lz - Arhive file
  • lzh - LZH archive
  • m4a - Audio-only MPEG-4 files
  • m4b - Audiobook and podcast MPEG-4 files, which also contain metadata including chapter markers, images, and hyperlinks
  • m4p - MPEG-4 files with audio streams encrypted by FairPlay Digital Rights Management as were sold through the iTunes Store
  • m4v - MPEG-4 Visual bitstreams
  • mid - Musical Instrument Digital Interface file
  • mie - Dedicated meta information format which supports storage of binary as well as textual meta information
  • mj2 - Motion JPEG 2000
  • mkv - Matroska video file
  • mobi - Mobipocket
  • mov - QuickTime video file
  • mp1 - MPEG-1 Audio Layer I
  • mp2 - MPEG-1 Audio Layer II
  • mp3 - Audio file
  • mp4 - MPEG-4 Part 14 video file
  • mpc - Musepack (SV7 & SV8)
  • mpg - MPEG-1 file
  • mts - MPEG-2 Transport Stream, both raw and Blu-ray Disc Audio-Video (BDAV) versions
  • mxf - Material Exchange Format
  • nef - Nikon Electronic Format image file
  • nes - Nintendo NES ROM
  • odp - OpenDocument for presentations
  • ods - OpenDocument for spreadsheets
  • odt - OpenDocument for word processing
  • oga - Audio file
  • ogg - Audio file
  • ogm - Audio file
  • ogv - Audio file
  • ogx - Audio file
  • opus - Audio file
  • orf - Olympus Raw image file
  • otf - OpenType font
  • pcap - Libpcap File Format
  • pdf - Portable Document Format
  • pgp - Pretty Good Privacy
  • png - Portable Network Graphics
  • pptx - Microsoft Powerpoint
  • ps - Postscript
  • psd - Adobe Photoshop document
  • qcp - Tagged and chunked data
  • raf - Fujifilm RAW image file
  • rar - Archive file
  • rpm - Red Hat Package Manager file
  • rtf - Rich Text Format
  • rw2 - Panasonic RAW image file
  • s3m - Audio module format: ScreamTracker 3
  • shp - Geospatial vector data format
  • skp - SketchUp
  • spx - Audio file
  • sqlite - SQLite file
  • stl - Standard Tesselated Geometry File Format (ASCII only)
  • swf - Adobe Flash Player file
  • tar - Tarball archive file
  • tif - Tagged Image file
  • ttf - TrueType font
  • vcf - vCard
  • voc - Creative Voice File
  • wasm - WebAssembly intermediate compiled format
  • wav - Waveform Audio file
  • webm - Web video file
  • webp - Web Picture format
  • woff - Web Open Font Format
  • woff2 - Web Open Font Format
  • wv - WavPack
  • xcf - eXperimental Computing Facility
  • xlsx - Microsoft Excel
  • xm - Audio module format: FastTracker 2
  • xml - eXtensible Markup Language
  • xpi - XPInstall file
  • xz - Compressed file
  • zip - Archive file
  • zst - Archive file

Pull requests are welcome for additional commonly used file types.

The following file types will not be accepted:

file-type for enterprise

Available as part of the Tidelift Subscription.

The maintainers of file-type and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.

Related

Maintainers

Download Details:

Author: Sindresorhus
Source Code: https://github.com/sindresorhus/file-type 
License: MIT license

#javascript #file #type #node 

File-type: Detect The File Type Of A Buffer/Uint8Array/ArrayBuffer