To test if a file is readable, you try to open it. If you get an error, then it's not readable. You need to either trap or catch exceptions or stop on errors, as appropriate. Remember, Windows locks files that are open for writing, so applications need to expect that they sometimes can't open a file.  
If you absolutely have to, you can use something like this to test if you can read a file:
try {
    [System.IO.File]::OpenRead($FullPathName).Close()
    $Readable = $true
}
catch {
    $Readable = $false        
}
And this to test if you can write to a file:
try {
    [System.IO.File]::OpenWrite($FullPathName).Close()
    $Writable = $true
}
catch {
    $Writable = $false        
}
That logic is fairly easy to wrap into a function if you really need it.
As far as file types, nearly everything in the file system in Windows is a plain file or a directory, since Windows doesn't have the "everything is a file" convention. So, normally you can test as follows:
# Test if file-like
Test-Path -Path $Path -Leaf
# Test if directory-like
Test-Path -Path $Path -Container
If you're working with a FileInfo or DirectoryInfo object (i.e., the output of Get-Item, Get-ChildItem, or a similar object representing a file or directory) you'll have the PSIsContainer property which will tell you if the item is a file or a directory.
That covers probably 99.999% of cases.
However, if you need to know if something is an NTFS hard link to a file (rare, but oldest), an NTFS junction to a directory, an NTFS symlink, an NTFS volume mount point, or any type of NTFS reparse point, it gets much more complicated.  [This answer does a good job describing the first three.]
Let's create a simple NTFS folder to test with:
# Create a test directory and change to it.
New-Item -Path C:\linktest -ItemType Directory | Select-Object -ExpandProperty FullName | Push-Location
# Create an empty file
New-Item -Path .\file1 -ItemType file -Value $null | Out-Null
New-Item -Path .\file2 -ItemType file -Value $null | Out-Null
# Create a directory
New-Item -Path .\dir1 -ItemType Directory | Out-Null
# Create a symlink to the file
New-Item -ItemType SymbolicLink -Path .\sfile1 -Value .\file1 | Out-Null
# Create a symlink to the folder
New-Item -ItemType SymbolicLink -Path .\sdir1 -Value .\dir1 | Out-Null
# Create a hard link to the file
New-Item -ItemType HardLink -Path .\hfile1 -Value .\file1 | Out-Null
# Create a junction  to the folder
New-Item -ItemType Junction -Path .\jdir1 -Value .\dir1 | Out-Null
# View the item properties
Get-ChildItem -Path . | Sort-Object Name | Format-Table -Property Name, PSIsContainer, LinkType, Target, Attributes -AutoSize
Your output will be:
Name   PSIsContainer LinkType     Target                            Attributes
----   ------------- --------     ------                            ----------
dir1            True              {}                                 Directory
file1          False HardLink     {C:\linktest\hfile1}                 Archive
file2          False              {}                                   Archive
hfile1         False HardLink     {C:\linktest\file1}                  Archive
jdir1           True Junction     {C:\linktest\dir1}   Directory, ReparsePoint
sdir1           True SymbolicLink {C:\linktest\dir1}   Directory, ReparsePoint
sfile1         False SymbolicLink {C:\linktest\file1}    Archive, ReparsePoint
Note that both file1 and hfile1 are hard links, even though file1 wasn't created as such.
To clean up the above garbage, do:
Get-ChildItem -Path C:\linktest\ | ForEach-Object { $_.Delete() }
There's a bug in Remove-Item with deleting some container links which prevents the command from removing the items.
The general solution would be to get the item and test it:
# Get the item. Don't use Get-ChildItem because that will get a directory's contents
$Item = Get-Item -Path $Path
# Is it a container
$Item.PSIsContainer
# Is it a link of some kind?
[System.String]::IsNullOrWhiteSpace($Item.LinkType)
$Item.LinkType -eq 'Junction'
# Is it a Reparse Point?
($Item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -eq [System.IO.FileAttributes]::ReparsePoint
There are several other potential attributes, too:
PS> [System.Enum]::GetNames([System.IO.FileAttributes])
ReadOnly
Hidden
System
Directory
Archive
Device
Normal
Temporary
SparseFile
ReparsePoint
Compressed
Offline
NotContentIndexed
Encrypted
IntegrityStream
NoScrubData
Note that Device is documented as reserved for future use.  Ain't no device file type in Windows.
For volume mount points, I'm not 100% sure how those look.  I know you can create them on Windows 8.1 and later with Get-Partition followed by an appropriate Add-PartitionAccessPath, but I'm on Windows 7 currently.  I'm afraid I have no means of testing this at the moment.
Finally, I have no idea how exactly PowerShell Core 6.0 on Linux handles file types.