Reputation: 1249
I have a simple function that takes a function as it's argument and returns a new function. I get Object is of type 'unknown'
when calling the returned function
const makeFunction = <T>(callback: (someParam: number, options: T) => any) => {
return (options: T) => {
const param = 4;
return callback(param, options)
}
}
Above code is okay for typescript but when I am calling function I get complaint
makeFunction((param, options) => {
const a = options.optionsValue //(parameter) options: unknown, Object is of type 'unknown'
})({optionsValue: 'some value'})
Upvotes: 118
Views: 331216
Reputation: 21
You have 2 options:
try {
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
} else {
console.error('An unknown error occurred');
}
}
try {
} catch (error) {
const err = error as Error;
console.error(err.message);
}
Upvotes: 0
Reputation: 229
I took such as error while useState. I describe for error usestate:
'''`const[error, setError]=useState(String);`
and as for that catch block
catch (ex) {
let erMssg = "exceptional";
if (ex instanceof Error) {
erMssg = ex.message;
}
setError(erMssg );
setLoading(false);
}
Upvotes: 0
Reputation: 6337
I stumbled on this while coding in Angular, and it occurs within the *ngFor
loop using the keyvalue
pipe. In such loops, if the value is an object, TypeScript needs to know the type of the key and the value. So when initializing the object you're going to be iterating through using *ngFor
, be certain to precise what type is expected of the key and what type is expected of the value, like so:
some_object: {[key: number]: string} = {2: 'foo', 1: 'bar'};
Upvotes: 0
Reputation: 9
simply put "any" after the catch error message, it should work.
`try {
} catch (error: any) {
console.log(error.message); }`
Upvotes: -1
Reputation: 2608
updating my tsconfig.json
with the following has worked for me:
"useUnknownInCatchVariables": false,
Update:
you need to put it like this under compilerOptions
"compilerOptions": {
"useUnknownInCatchVariables": false
}
Note: You need Typescript v4.4 or higher to be able to use this compiler option else you get a compiler error.
npm install -g ts-node@latest
npm install -g typescript@latest
Upvotes: 116
Reputation: 4669
This I have used, this will allow you to do gridObj.
, custom properties
let gridobj : any = this.$refs.grid;
gridobj.columns(col, "add");
Upvotes: 0
Reputation: 1807
I got this issue in a try/catch
bumping the Typescript to version 4.4 and found in the documentation the explanation for that.
In resume they added the flag useUnknownInCatchVariables
that is true by default if strict
. It basically changes the type of the error in a catch
from any
to unknown
causing this issue.
So in order to bump to 4.4 you have some options:
try {
...
} catch(e) {
console.log((e as Error).message)
}
or:
try {
...
} catch(e) {
if (e instanceof Error) {
console.log(e.message)
}
}
or in your tsconfig.json
you can explicitly set the flag to false
:
{
"compilerOptions": {
"strict": true,
"useUnknownInCatchVariables": false
}
}
Upvotes: 56
Reputation: 2822
You can use casting: (err as Error)
I like the if
statement solution, but this also works:
catch (error) {
let msg = (error as Error).message;
}
Upvotes: 26
Reputation: 7315
Issue with TS 4.0 explained here: https://devblogs.microsoft.com/typescript/announcing-typescript-4-0/#unknown-on-catch
All of the other answers didn't work for me but using the isAxiosError
worked just fine:
} catch (error) {
if (axios.isAxiosError(error)) {
const errResp = error.response;
// Handle your error type safe here
} else {
// Handle the unknown
}
}
No Object is of type 'unknown'.ts(2571)
error anymore.
Upvotes: 14
Reputation: 9713
Since this is the first result you get when you google Object is of type 'unknown'
, I want to post my case. It might help future readers. This is not the answer to OP's question.
I got this error in the catch
block. After debugging for a while I came to know that starting typescript v4.0, catch clause variables have type unknown
instead of any
.
And according to docs:
unknown is safer than any because it reminds us that we need to perform some sort of type-checks before operating on our values.
My code looked something like this before v4.0:
try {
// try something exceptional here
} catch (error) {
console.log(error.message);
}
And to fix this error, I had to put an additional if
check on error
variable.
try {
// try something exceptional here
} catch (error) {
let errorMessage = "Failed to do something exceptional";
if (error instanceof Error) {
errorMessage = error.message;
}
console.log(errorMessage);
}
Upvotes: 166
Reputation: 199
Add a type to the calling function like this:
function(): Observable<any>
to avoid it from returnig unknown
.
Upvotes: 2
Reputation: 20142
We need to think how TS can infer the type from this definition. TS can understand type from two places:
In your use case you don't provide type in any of those places and this is the reason you get unknown
, because how TS can know what argument type you need. In order to give TS possibility to understand the type you can do or:
Set explicitly generic by:
makeFunction<YourType>((param, options) => {...))
Set type in callback function by for example defining one beforehand:
const f = (a: number, b: {a: string}) => b // here types are set
makeFunction(f)({a: 'some value'}) // makeFunction is able to infer the types by f
You can also do this inline by saying ((param: number, options: MyType))
options
can be dynamicI believe you want below behavior:
const makeFunction = <F extends (someParam: number, options: any) => any>(callback: F) => {
return (options: Parameters<F>[1]) => {
const param = 4;
return callback(param, options)
}
}
const f = (a: number, b: {a: string}) => b
makeFunction(f)({ a: 'a' })
const g = (a: number, b: {b: number}) => b
makeFunction(g)({b: 1})
We say few things:
F
is now function which extends from binary function, and we directly infer its typeParameters<F>[1]
is second argument type of given function F
typeUpvotes: 18
Reputation: 49
Create an interface for options or use any as type,
makeFunction((param, options: any) => {
const a = options.optionsValue;
})({optionsValue: 'some value'});
Typescript takes options type as {} which causes issue during compilation.
Upvotes: 3