postcode
    TypeScript icon, indicating that this package has built-in type declarations

    5.1.0 • Public • Published

    Postcode.js

    Validate & parse UK postcodes

    CI codecov Dependencies Release

    Size Downloads Try postcode on RunKit

    Utility methods for UK Postcodes, including validating the shape of a postcode, extracting postcode elements (like incodes, outcodes, areas and more).

    Tested against ~1.7 million postcodes on ONSPD.

    Features

    Links

    Guides

    Getting Started

    Installation

    npm install postcode

    Validate

    import { isValid } from "postcode";
    
    isValid("AA1 1AB"); // => true

    Parse

    Pass a string to parse. This will return a valid or invalid postcode instance which can be easily destructured.

    Valid Postcode

    ValidPostcode type definition

    import { parse } from "postcode";
    
    const {
      postcode,    // => "SW1A 2AA"
      outcode,     // => "SW1A"
      incode,      // => "2AA"
      area,        // => "SW"
      district,    // => "SW1"
      unit,        // => "AA"
      sector,      // => "SW1A 2"
      subDistrict, // => "SW1A"
      valid,       // => true
    } = parse("Sw1A     2aa");

    Invalid Postcode

    InvalidPostcode type definition

    const {
      postcode,    // => null
      outcode,     // => null
      incode,      // => null
      area,        // => null
      district,    // => null
      unit,        // => null
      sector,      // => null
      subDistrict, // => null
      valid,       // => false
    } = parse("    Oh no, ):   ");

    Type Guard

    The TypeScript compiler can infer if you have a valid postcode type from parse by checking the valid attribute

    import { parse } from "postcode";
    
    const postcode = parse("SW1A 2AA");
    
    if (postcode.valid) {
      // `postcode` adheres to the `ValidPostcode` interface
      processString(postcode.outcode.toLowerCase()); // TypeScript compiler knows `outcode` to be a string
      processString(postcode.subDistrict.toLowerCase()); // And it will throw errors on common gotchas (e.g. subdistrict can be `null` on a valid postcode)
    } else {
      // `postcode` adheres to the `InvalidPostcode` interface
      processInvalidPostcode(postcode);
    }

    Valid Postcode Object

    Postcode .outcode .incode .area .district .subDistrict .sector .unit
    AA9A 9AA AA9A 9AA AA AA9 AA9A AA9A 9 AA
    A9A 9AA A9A 9AA A A9 A9A A9A 9 AA
    A9 9AA A9 9AA A A9 null A9 9 AA
    A99 9AA A99 9AA A A99 null A99 9 AA
    AA9 9AA AA9 9AA AA AA9 null AA9 9 AA
    AA99 9AA AA99 9AA AA AA99 null AA99 9 AA

    Exported Methods

    If you're just after a single value, you can import a single method.

    Validation

    isValid("Sw1A 2aa"); // => true

    Formatting

    import {
      toNormalised,
      toOutcode,
      toIncode,
      toArea,
      toDistrict,
      toSubDistrict,
      toSector,
      toUnit,
    } from "postcode";
    
    toNormalised("Sw1A 2aa");  // => "SW1A 2AA"
    toOutcode("Sw1A 2aa");     // => "SW1A"
    toIncode("Sw1A 2aa");      // => "2AA"
    toArea("Sw1A 2aa");        // => "AA"
    toDistrict("Sw1A 2aa");    // => "SW1"
    toSubDistrict("Sw1A 2aa"); // => "SW1A"
    toSector("Sw1A 2aa");      // => "SW1A 2"
    toUnit("Sw1A 2aa");        // => "AA"

    Fix

    fix Attempts to correct and clean up a postcode without validating by replacing commonly misplaced characters (e.g. mixing up 0 and "O", 1 and "I"). This method will also uppercase and fix spacing. The original input is returned if it cannot be reliably fixed.

    fix("SWIA 2AA") => "SW1A 2AA" // Corrects I to 1
    fix("SW1A 21A") => "SW1A 2IA" // Corrects 1 to I
    fix("SW1A OAA") => "SW1A 0AA" // Corrects O to 0
    fix("SW1A 20A") => "SW1A 2OA" // Corrects 0 to O
    
    // Other effects
    fix(" SW1A  2AO") => "SW1A 2AO" // Properly spaces
    fix("SW1A 2A0") => "SW1A 2AO" // 0 is coerced into "0"

    Aims to be used in conjunction with parse to make postcode entry more forgiving:

    const { inward } = parse(fix("SW1A 2A0")); // inward = "2AO"

    If the input is not deemed fixable, the original string will be returned

    fix("12a") => "12a"

    Extract & Replace

    match. Retrieve valid postcodes in a body of text

    const matches = match("The PM and her no.2 live at SW1A2aa and SW1A 2AB"); // => ["SW1A2aa", "SW1A 2AB"]
    
    // Perform transformations like normalisation using `.map` and `toNormalised`
    matches.map(toNormalised); // => ["SW1A 2AA", "SW1A 2AB"]
    matches.map(toOutcode); // => ["SW1A", "SW1A"]
    
    // No matches yields empty array
    match("Some London outward codes are SW1A, NW1 and E1"); // => []

    replace. Replace postcodes in a body of text, returning the updated corpus and any matching postcodes

    const { match, result } = replace("The PM and her no.2 live at SW1A2AA and SW1A 2AB");
    // => match: ["SW1A2AA", "SW1A 2AB"]
    // => result: "The PM and her no.2 live at  and "
    
    // Add custom replacement
    replace("The PM lives at SW1A 2AA", "Downing Street");
    // => { match: ["SW1A 2AA"], result: "The PM lives at Downing Street" };
    
    // No match
    replace("Some London outward codes are SW1A, NW1 and E1");
    // => { match: [], result: "Some London outward codes are SW1A, NW1 and E1" }

    Version 5.0.0

    5.0.0 brings changes which allows for better treeshaking and interopability with ES Modules. It also deprecates legacy class based APIs in favour of single purpose methods.

    Breaking Changes

    • postcode no longer exports a class. Legacy new Postcode() functionality has been removed. Methods attached to Postcode are all available as named exports.
    • postcode no longer uses default exports. All exports are named. E.g.
    // In <= 4.0.0
    import Postcode from "postcode";
    Postcode.parse("SW1A 2AA");
    
    // In >= 5.0.0
    import { parse } from "postcode";
    parse("SW1A 2AA");

    In many cases, migration can be achieved by changing import Postcode from "postcode" to import * as Postcode from "postcode", however this gives up treeshaking advantages.

    New Features

    • postcode now exports a ES Module build
    • Exports regular expressions
    • match accepts a string and returns all valid postcodes
    • replace accepts a string and replaces valid postcodes with an optional second argument. Default replacement text is empty string ""

    Definitions

    See the postcode format guide for a glossary of postcode component terms.

    Notes

    Postcodes cannot be validated just with a regular expression (however complex). True postcode validation requires having a full list of postcodes to check against. Relying on a regex will produce false postives/negatives.

    See the postcode validation guide for an overview of the approaches and tradeoffs associated with postcode validation.

    Testing

    npm test

    License

    MIT

    Contains Ordnance Survey Data © Crown Copyright & Database Right

    Install

    npm i postcode

    DownloadsWeekly Downloads

    10,209

    Version

    5.1.0

    License

    MIT

    Unpacked Size

    50.2 kB

    Total Files

    9

    Last publish

    Collaborators

    • cablanchard