Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
TypeScript tiny narrowing helpers you better use.
npm i narrowing # yarn add narrowing
let a: unknown;
if (isXXX(a)) {
// TypeScript know your type here!
}
Basic:
Advanced:
These functions help you make advanced type guards.
import {
isArray,
isBigInt,
isBoolean,
isFunction,
isInstance,
isNil,
isNull,
isNumber,
isObject,
isString,
isSymbol,
isUndefined
} from 'narrowing';
let a: unknown;
if (isString(a)) a.toLocaleLowerCase();
if (isNumber(a)) a.toFixed();
if (isBigInt(a)) a.toString();
if (isBoolean(a)) a.valueOf();
if (isSymbol(a)) a.toString();
if (isUndefined(a)) {
a; // undefined
}
if (isNull(a)) {
a; // null
}
if (isNil(a)) {
a; // null | undefined
}
function testFunc(a: string, b: number): boolean {
return true;
}
if (isFunction<typeof testFunc>(a)) {
a('11', 1); // no error
}
if (isInstance(a, Date)) {
a.getFullYear();
}
class TestClass {
m() {}
}
if (isInstance(a, TestClass)) {
a.m();
}
if (isArray<string>(a)) {
a[0].trim();
}
let b: TestClass | undefined | null;
// b.m(); // Error: Object is possibly 'null' or 'undefined'.ts(2533)
if (!isNil(b)) {
b.m(); // no Error any more
}
if (isObject(a)) {
// let a: {
// [key: string]: unknown;
// };
a;
}
has()
Check if a type has a property
TypeScript Handbook / Using type predicates
type Bird = { fly: () => {} };
type Cat = { run: () => {}; meow: () => {} };
type Dog = { run: () => {} };
let pet = {} as any;
// save these type guards somewhere and reuse them
const isBird = has<Bird>('fly');
const isDogOrCat = has<Dog | Cat>('run');
const isCat = has<Cat>('run', 'meow');
if (isBird(pet)) {
pet.fly(); // Bird
}
if (isDogOrCat(pet)) {
pet.run(); // Dog | Cat
}
if (isCat(pet)) {
pet.meow(); // Cat
}
kind()
TypeScript handbook / Discriminated unions
interface Square {
kind: 'square';
size: number;
}
interface Rectangle {
kind: 'rectangle';
width: number;
height: number;
}
interface Circle {
kind: 'circle';
radius: number;
}
const isSquare = kind<Square>('square');
const isRectangle = kind<Rectangle>('circle');
const isCircle = kind<Circle>('circle');
let s = {} as any;
if (isSquare(s)) {
console.log(s.size);
}
if (isRectangle(s)) {
console.log(s.height);
}
if (isCircle(s)) {
console.log(s.radius);
}
literal()
const is404 = literal(404);
let code = 200;
if (is404(code)) {
// code's type should be 404 , not number
// let code: 404
code;
}
this is useful when you see schema()
schema()
Basic schema validation
let message: unknown = {
code: 200,
msg: 'success',
records: [
{ id: 1, name: 'aaa' },
{ id: 2, name: 'bbb' },
{ id: 3, name: 'ccc' }
]
};
const isSuccess = schema({
code: literal(200),
msg: isString,
records: isArray
});
if (isSuccess(message)) {
// let message: {
// code: 200;
// msg: string;
// records: unknown[];
// }
message;
}
schema supports a type argument for associating a schema with an existing type
interface TestInterface {
id: number;
name: string;
}
const isTestInterface = schema<TestInterface>({
id: isNumber,
name: isString
});
if (isTestInterface(message)) {
// let message: TestInterface
message;
}
every()
Runtime array type validation. Checks each element of an array.
let arr: unknown[] = [1, 2, 3];
if (every(isNumber)(arr)) {
let typeCheck: number[] = arr;
}
Works with any narrowing validator, including schemas.
interface TestInterface {
id: number;
name: string;
}
const isTestInterface = schema<TestInterface>({
id: isNumber,
name: isString
});
let arr: unknown[] = [{ id: 1, name: 'aaa' }];
if (every(isTestInterface)(arr)) {
let typeCheck: TestInterface[] = arr;
}
has()
has()
accept multiple paramskind()
isObject()
, isValidObject()
isValidObject()
schema()
literal()
every()
FAQs
TypeScript tiny narrowing helpers you better use.
We found that narrowing demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.