any
TypeRepresents all possible TS types and JS values.
any
is a top type (universal supertype) of the type system
any
type is too permissive
any
type, it's easy to pass type check, but fail at runtimeunknown
TypeType-safe counterpart of any
type.
This is similar to the any
type, but is safer because it’s not legal to do anything with an unknown
value
let unknownValue: unknown; unknownValue = 10; unknownValue = 'height'; if (typeof unknownValue == 'string') { const unknownKey = unknownValue.toUpperCase(); // Do something with unknownKey } else if (typeof unknownValue == 'number') { // Do something else when it is a number type }
With unknown
if you do not check the type, the linter
will show a type error
, because you are trying to use a method in an object whose type you don't know for sure, which can cause errors in execution time
unknown
type is only assignable to the any
type and unknown
type.
We can narrow type using typeof
, instanceof
, or custom type guard operators.
See
Control Flow Based Type Analysis
Section
function unknownNarrowing(value: unknown): string { if (typeof value === "string") { // here, the value is string return `${value}`; } if (value instanceof Number) { // here, the value is Number // Number(value) would return NaN return +value; } return String(value); }
// type checking every element in value is number function isValueStringInArray(value: unknown): value is string[] { return ( Array.isArray(value) && value.every(el => typeof el === "string") ); } const unknownValue: unknown = ["hi", "bye", "this"]; if (isValueStringInArray(unknownValue)) { // if every element in value is a string, log the whole thing out console.log(unknownValue); }
unknown
Considered cheating the type system to make two incompatible types compatible
Below example takes mockType
object and cases it as unknown
unknown
type object to ArbitraryOverrideType
to force the compiler to understand mockType
as as ArbitraryOverrideType
const mockType = ({ id: 1, random_attribute: "something", uncompliant_attribute: "not compliant" } as unknown) as ArbitraryOverrideType
Below is an inversify test for mockedService
jest.fn()
After mocking the methods, we cast the service as a whole to an unknown
type
const mockedService = { getById: jest.fn(), getByIds: jest.fn(), } as unknown; // force-casted here container .bind<SomeService>(ServiceTypes.SomeService) .toConstantValue(mockedService as ISomeOtherService);