'Type of expression is ambiguous without more context Swift
I am getting a 'Type of expression is ambiguous without more context ' on this part of code from a project I am trying to upgrade to latest Swift version. I can't seem to figure it out. I tried different things but can't get it to work.
The problem is on the syntax of this line
let imageToDeleteParameters = imagesToDelete.map { ["id": $0.id, "url": $0.url.absoluteString, "_destroy": true] }
Full code:
extension TutorialCreationRequest: WebserviceParametrable {
func toParameters() -> [String: AnyObject] {
let imageParameters = images.map { ["url": $0] }
let imageToDeleteParameters = imagesToDelete.map { ["id": $0.id, "url": $0.url.absoluteString, "_destroy": true] }
return [
"title": title,
"is_draft": isDraft,
"difficulty": difficulty,
"duration": duration,
"cost": cost,
"user_id": userId,
"description": description,
"to_sell": toSell,
"images": [imageParameters, imageToDeleteParameters].flatMap { $0 }
]
}
}
Solution 1:[1]
This happens when you have a function with wrong argument names.
Example:
functionWithArguments(argumentNameWrong: , argumentName2: )
and You declared your function as:
functionWithArguments(argumentName1: , argumentName2: ){}
This usually happens when you changed the name of a Variable. Make sure you refactor when you do that.
Solution 2:[2]
This can happen if any part of your highlighted method or property is attempting to access a property or method with the incorrect type.
Here is a troubleshooting checklist, make sure:
- the type of arguments match in the call site and implementation.
- the argument names match in the call site and implementation.
- the method name matches in the call site and implementation.
- the returned value of a property or method matches in the usage and implementation (ie:
enumerated()
) - you don't have a duplicated method with potentially ambiguous types such as with protocols or generics.
- the compiler can infer the correct type when using type inference.
A Strategy
- Try breaking apart your method into a greater number of simpler method/implementations.
For example, lets say you are running compactMap
on an array of custom Types. In the closure you are passing to the compactMap
method, you initialize and return another custom struct. When you get this error, it is difficult to tell which part of your code is offending.
- For debugging purposes, you can use a
for in
loop instead ofcompactMap
. - instead of passing the arguments, directly, you can assign them to constants in the for loop.
By this point, you may come to a realization, such as, instead of the property you thought you wanted to assign actually had a property on it that had the actual value you wanted to pass.
Solution 3:[3]
Not an answer to this question, but as I came here looking for the error others might find this also useful:
For me, I got this Swift error when I tried to use the for (index, object)
loop on an array without adding the .enumerated()
part ...
Solution 4:[4]
The compiler can't figure out what type to make the Dictionary, because it's not homogenous. You have values of different types. The only way to get around this is to make it a [String: Any]
, which will make everything clunky as all hell.
return [
"title": title,
"is_draft": isDraft,
"difficulty": difficulty,
"duration": duration,
"cost": cost,
"user_id": userId,
"description": description,
"to_sell": toSell,
"images": [imageParameters, imageToDeleteParameters].flatMap { $0 }
] as [String: Any]
This is a job for a struct. It'll vastly simplify working with this data structure.
Solution 5:[5]
I had this message when the type of a function parameter didn't fit. In my case it was a String instead of an URL.
Solution 6:[6]
Explicitly declaring the inputs for that mapping function should do the trick:
let imageToDeleteParameters = imagesToDelete.map {
(whatever : WhateverClass) -> Dictionary<String, Any> in
["id": whatever.id, "url": whatever.url.absoluteString, "_destroy": true]
}
Substitute the real class of "$0" for "WhateverClass" in that code snippet, and it should work.
Solution 7:[7]
I got this error when I put a space before a comma in the parameters when calling a function.
eg, I used:
myfunction(parameter1: parameter1 , parameter2: parameter2)
Whereas it should have been:
myfunction(parameter1: parameter1, parameter2: parameter2)
Deleting the space got rid of the error message
Solution 8:[8]
In my case, this error message shown when I don't added optional property to constructor.
struct Event: Identifiable, Codable {
var id: String
var summary: String
var description: String?
// also has other props...
init(id: String, summary: String, description: String?){
self.id = id
self.summary = summary
self.description = description
}
}
// skip pass description
// It show message "Type of expression is ambiguous without more context"
Event(
id: "1",
summary: "summary",
)
// pass description explicity pass nil to description
Event(
id: "1",
summary: "summary",
description: nil
)
but it looks always not occured.
I test in my playground this code, it show warning about more concrete
var str = "Hello, playground"
struct User {
var id: String
var name: String?
init(id: String, name: String?) {
self.id = id
self.name = name
}
}
User(id: "hoge") // Missing argument for parameter 'name' in call
Solution 9:[9]
For me the case was Type inference I have changed the function parameters from int To float but did not update the calling code, and the compiler did not warn me on wrong type passed to the function
Before
func myFunc(param:Int, parma2:Int) {}
After
func myFunc(param:Float, parma2:Float) {}
Calling code with error
var param1:Int16 = 1
var param2:Int16 = 2
myFunc(param:param1, parma2:param2)// error here: Type of expression is ambiguous without more context
To fix:
var param1:Float = 1.0f
var param2:Float = 2.0f
myFunc(param:param1, parma2:param2)// ok!
Solution 10:[10]
My problem were the parameters without default value
I changed
let contaPadrao = RedeConta(agencia: cPadrao?.agencia,
conta: cPadrao?.conta,
dac: cPadrao?.dac)
to
let contaPadrao = RedeConta(agencia: cPadrao?.agencia ?? "",
conta: cPadrao?.conta ?? "",
dac: cPadrao?.dac ?? "")
Solution 11:[11]
You have two " "
before the =
let imageToDeleteParameters = imagesToDelete.map { ["id": $0.id, "url": $0.url.absoluteString, "_destroy": true] }
Solution 12:[12]
In my case it happened with NSFetchedResultsController and the reason was that I defined the NSFetchedResultsController for a different model than I created the request for the initialization (RemotePlaylist vs. Playlist):
var fetchedPlaylistsController:NSFetchedResultsController<RemotePlaylist>!
but initiated it with a request for another Playlist:
let request = Playlist.createFetchRequest()
fetchedPlaylistsController = NSFetchedResultsController(fetchRequest: request, ...
Solution 13:[13]
In my case, I ran into this error when I was creating a distribution build, and a class was referring to Debug only context method.
Something like this. Try compiling the below class for the Distribution build.
class MyClass {
func sayHello() {
helloWorld()
}
#if DEBUG
func helloWorld() {
print("Hello world")
}
#endif
}
Solution 14:[14]
In my case, the arguments I was passing had optional String
values. Providing a default value to fall back on ( in case the value is nil
) solved this issue for me.
I changed this -
router?.pushToDetailsScreen(
gitHubRepositoryOwnerName: gitHubRepositoryDetails?[index].owner?.login,
gitHubRepositoryName: gitHubRepositoryDetails?[index].name,
avatarUrl: gitHubRepositoryDetails?[index].owner?.avatar_url)
to this -
router?.pushToDetailsScreen(
gitHubRepositoryOwnerName: gitHubRepositoryDetails?[index].owner?.login ?? "",
gitHubRepositoryName: gitHubRepositoryDetails?[index].name ?? "",
avatarUrl: gitHubRepositoryDetails?[index].owner?.avatar_url ?? "")
Solution 15:[15]
Make sure if there is any delegate methods are available with extension, then implement those and error will disappear.
Solution 16:[16]
This error could be shown due to multiple reasons. One of the most prominent reasons is a type mismatch. For example,
Suppose, parameter icons is a type of array and we passed an Enum as IconDismiss.
## Wrong
text.config = TextField.Config(isClearable: true, icons: IconDismiss)
## Correct
text.config = TextField.Config(isClearable: true, icons: [IconDismiss])
Solution 17:[17]
As theEye's answer it is not an answer to this question, but as I also came here looking for the error im posting my case as others might find this also useful:
I got this error message when I was by error trying to calculate a value of two different types.
In my case I was trying to divide a CGFloat
by a Double
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow