I've been working with TypeScript quite a bit lately and stumbled across a problem that is confusing to me. I've put the problem into an example which looks like the following:
type Options<T> = {
props: T;
g: (x: T) => void;
};
function f<T>(options: Options<T>) {
console.log(options);
}
// Example 1 (x and props expected type)
f({
props: {
foo: {
a: 200,
bar: () => {}
}
},
g(x) {
// x is the expected type
console.log(x)
}
});
// Example 2 (x and props unknown)
f({
props: {
foo: {
a: 100,
bar: function() {}
}
},
g(x) {
// x is unknown
console.log(x)
}
});
When hovering over props
in the first example, you will see that it has the expected type. And although barely anything changed in the second example props
is of type unknown
. Why is that? Here is the example above in TS Playground.
Anything is assignable to unknown , but unknown is not assignable to anything but itself. So we can do const foo: unknown = 'foo' , but we cannot do, out of the box, const bar: string = foo if foo is unknown .
Typescript doesn't allow you to use an unknown type before casting it. You would need to cast it, in order to typescript to allow you to use it. As you can see from the above examples, the unknown type forces you to determine what a variable typed as unknown is, either through type casting or type narrowing.
The "Object is of type unknown" error occurs when we try to access a property on a value that has a type of unknown . To solve the error, use a type guard to narrow down the type of the object before accessing a property, e.g. if (err instanceof Error) {} . Copied!
unknown and any are 2 special types that can hold any value. unknown is recommended over any because it provides safer typing — you have to use type assertion or narrow to a specific type if you want to perform operations on unknown .
TypeScript provides a variety of type definitions. Some of them are common such as strings, numbers, arrays, booleans to more custom interfaces and classes. New types came with the release of TypeScript 3.0. One of them is the unknown type which we will cover in this article. What is the Unknown Type? Anything is assignable to unknown.
Typescript is just a type system: all those types just get thrown away when it compiles, it won’t change your code for you. You’re also declaring an undefined variable ( let str; ), and the type of that is unknown. You then assign a string to it. This isn’t an issue, TS will allow this.
The "Type 'unknown' is not assignable to type" error occurs when we try to assign a value with a type of `unknown` to a value of a different type. To solve the error, use a type assertion or a type guard to verify that the two values have compatible types before the assignment. HomeAboutContacts HomeAboutContacts GitHubLinkedinTwitter
To solve the "Uncaught SyntaxError: Unexpected token import" in TypeScript, set the module option to commonjs in your tsconfig.json file and make sure to compile your TypeScript files (e.g. with ts-node), and not to run them directly with node. Open your tsconfig.json file and make sure the module option is set to commonjs.
This is a design limitation in TypeScript; see microsoft/TypeScript#38845. Apparently (from this comment):
An arrow function with no parameters is not context sensitive, but a function expression with no parameters is context sensitive because of the implicit
this
parameter. Anything that is context sensitive is excluded from the first phase of type inference, which is the phase that determines the types we'll use for contextually typed parameters.
It looks like inference for T
succeeds when the foo.bar
property is an arrow function because there's no contextual this
to worry about. And so a contextual type is successfully assigned to the x
parameter of g
, and everything proceeds as you want. But when the value of foo.bar
is a function expression, the compiler needs context to figure out what this
is, and T
cannot be inferred in time to figure out a contextual type for g
's parameter and it ends up becoming unknown
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With